//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest.hpp
 * @brief       iris unit test
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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-2017, 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          0x01160123u //!< iutest version 1.16.1.23
#define IUTEST_MAJORVER     0x01u       //!< Major Version
#define IUTEST_MINORVER     0x16u       //!< Minor Version
#define IUTEST_MICROVER     0x01u       //!< Micro Version
#define IUTEST_REVISION     0x23u       //!< Revision

#define IUTEST_BUILD        IUTEST_MICROVER //!< @deprecated

/**
 * @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-2017, 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
 * Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.\n
 \n
 * Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.\n
 \n
 * Neither the name of iutest nor the names of its
 contributors may be used to endorse or promote products derived from
 this software without specific prior 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_warning_into_error       </td><td>[yes|no]</td><td>Make warnings into error.</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. use a negative count to repeat forever.</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_WARNING_INTO_ERROR=0|1   </td><td>Make warnings into error.</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.16.2.0
    <ul>
      <li>警告をエラーとするオプション(--iutest_warning_into_error)を追加</li>
    </ul>
  </li>
  <li>v1.16.1.0
    <ul>
      <li>IUTEST_BUILD を非推奨に変更し、IUTEST_MICROVER を追加</li>
      <li>XML_OUTPUT_FILE 環境変数に対応</li>
    </ul>
  </li>
  <li>v1.16.0.0
    <ul>
      <li>iuwandbox で複数ソースファイルに対応</li>
      <li>例外アサーションで構造化例外（SEH）もキャッチできるように対応</li>
      <li>--iutest_filter のルールを Google Test 互換に修正</li>
    </ul>
  </li>
  <li>v1.15.2.0
    <ul>
      <li>IUTEST_TYPED_TEST_P に対して friend できるように IUTEST_FRIEND_TYPED_TEST_P_DECLARATION/IUTEST_FRIEND_TYPED_TEST_P を追加</li>
      <li>iuwandbox に --sprout/--msgpack オプションを追加</li>
      <li>iuwandbox の --list_compiler オプションでバージョンを出力しないように変更。--verbose を付けると以前と同じバージョン付きの出力をする</li>
      <li>iuwandbox で --expand_include オプションを付けなかった場合の include されたファイルの対応を修正</li>
      <li>iuwandbox の --boost オプションが Python3 で使えない問題を修正</li>
      <li>iuwandbox で未定義オプションを指定した場合にエラーにならない問題を修正</li>
      <li>IUTEST(A, B_C) と IUTEST(A_B, C) が名前の衝突でコンパイルエラーになる問題を修正</li>
      <li>色付きコンソールの自動判定を修正</li>
      <li>deprecated: IUTEST_HAS_STRSTREAM は将来的に削除されます</li>
      <li>deprecated: IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE は将来的に削除されます</li>
    </ul>
  </li>
  <li>v1.15.1.0
    <ul>
      <li>stderr に xml の内容を出力するリスナーを追加</li>
      <li>iuwandbox に xml 出力オプション(--xml, --junit)を追加</li>
      <li>--help|spec|feature|version を同時に使用可能に変更 (e.g. --spec --feature)</li>
      <li>CSV パラメータのパス解決処理を修正</li>
      <li>fused-src 生成ツールを修正</li>
    </ul>
  </li>
  <li>v1.15.0.0
    <ul>
      <li>--iutest_output オプションで repeat 回数のフォーマットに対応 e.g. --iutest_output=xml:test_%d.xml</li>
      <li>CSV ファイルから値のパラメータ作成に対応</li>
      <li>IUTEST_ALIAS_TESTNAME_F,IUTEST_JAPANESE_NAME_F の引数の順番を変更</li>
      <li>値のパラメータ化テストのテスト名指定方法を変更</li>
      <li>値のパラメータ化テストのテスト名指定方法の Google Test 互換対応</li>
      <li>IUTEST_TYPED_TEST_APPEND_TYPENAME を IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME に変更</li>
    </ul>
  </li>
  <li>v1.14.0.0
    <ul>
      <li>::iutest::Range を Enum に対応</li>
      <li>大幅なリファクタリング</li>
    </ul>
  </li>
  <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-2016, 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-2016, 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-2017, 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 internal definition
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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-2016, 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-2017, 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-2017, 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-2016, 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-2017, 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-2017, 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       portable
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, 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       internal definition
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, 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-2017, 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-2017, 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   //!< @deprecated native client to eol
#  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++17

//! is c++17 compiler
#if !defined(IUTEST_HAS_CXX17)
#  if (defined(__cplusplus) && __cplusplus >= 201406L)
#    define IUTEST_HAS_CXX17        1
#  elif defined(_MSVC_LANG) && _MSVC_LANG > 201402
#    define IUTEST_HAS_CXX17        1
#  endif
#endif

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

//! inline variable
#if !defined(IUTEST_HAS_INLINE_VARIABLE)
#if defined(__clang__)
#  if (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 9)) && IUTEST_HAS_CXX17
#    define IUTEST_HAS_INLINE_VARIABLE      1
#  endif
#endif
#endif

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

//! constexpr if
#if !defined(IUTEST_HAS_CONSTEXPR_IF)
#  if   defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606
#    define IUTEST_HAS_CONSTEXPR_IF         1
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1910 && IUTEST_HAS_CXX17
#      define IUTEST_HAS_CONSTEXPR_IF       1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_CONSTEXPR_IF)
#  define IUTEST_HAS_CONSTEXPR_IF           0
#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(_NATIVE_NULLPTR_SUPPORTED)
#    define IUTEST_HAS_NULLPTR      1
#  elif 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

#if !defined(IUTEST_NULLPTR)
#  if IUTEST_HAS_NULLPTR
#    define IUTEST_NULLPTR          nullptr
#  else
#    define IUTEST_NULLPTR          NULL
#  endif
#endif

//! auto
#if !defined(IUTEST_HAS_AUTO)
#  if   defined(__clang__)
#    if __has_feature(cxx_auto_type)
#      define IUTEST_HAS_AUTO   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_AUTO   1
#    endif
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1600
#      define IUTEST_HAS_AUTO   1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_AUTO   1
#    endif
#  endif
#endif

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

//! has decltype
#if !defined(IUTEST_HAS_DECLTYPE)
#  if   defined(__cpp_decltype) && __cpp_decltype >= 200707
#    define IUTEST_HAS_DECLTYPE     1
#  elif defined(__clang__)
#    if __has_feature(cxx_decltype)
#      define IUTEST_HAS_DECLTYPE   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_DECLTYPE   1
#    endif
#  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(__cpp_static_assert) && __cpp_static_assert >= 200410
#    define IUTEST_HAS_STATIC_ASSERT    1
#  elif defined(__clang__)
#    if __has_feature(cxx_static_assert)
#      define IUTEST_HAS_STATIC_ASSERT  1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_STATIC_ASSERT  1
#    endif
#  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(__cpp_constexpr) && __cpp_constexpr >= 200704
#    define IUTEST_HAS_CONSTEXPR    1
#  elif defined(__clang__)
#    if __has_feature(cxx_constexpr)
#      define IUTEST_HAS_CONSTEXPR  1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CONSTEXPR  1
#    endif
#  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

//! constexpr
#if IUTEST_HAS_CONSTEXPR
#  define IUTEST_CXX_CONSTEXPR          constexpr
#else
#  define IUTEST_CXX_CONSTEXPR
#endif

//! constexpr or const
#if IUTEST_HAS_CONSTEXPR
#  define IUTEST_CXX_CONSTEXPR_OR_CONST constexpr
#else
#  define IUTEST_CXX_CONSTEXPR_OR_CONST const
#endif

//! has rvalue reference
#if !defined(IUTEST_HAS_RVALUE_REFS)
#  if   defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610
#      define IUTEST_HAS_RVALUE_REFS    1
#  elif defined(__clang__)
#    if __has_feature(cxx_rvalue_references)
#      define IUTEST_HAS_RVALUE_REFS    1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_RVALUE_REFS    1
#    endif
#  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__)
     // private destractor = default is not works in gcc 4.5 - 4.6
#    if   (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 4)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_DEFAULT_FUNCTIONS  1
#    elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && 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(__cpp_initializer_lists) && __cpp_initializer_lists >= 200806
#    define IUTEST_HAS_INITIALIZER_LIST 1
#  elif defined(__clang__)
#    if __has_feature(cxx_generalized_initializers)
#      define IUTEST_HAS_INITIALIZER_LIST   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_INITIALIZER_LIST   1
#    endif
#  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(__cpp_variadic_templates) && __cpp_variadic_templates >= 200704
#    define IUTEST_HAS_VARIADIC_TEMPLATES   1
#  elif defined(__clang__)
#    if __has_feature(cxx_variadic_templates)
#      define IUTEST_HAS_VARIADIC_TEMPLATES 1
#    endif
#  elif defined(__GNUC__)
     // 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__ >= 8)) \
                || ((__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(__cpp_unicode_characters) && __cpp_unicode_characters >= 200704 && defined(__cpp_unicode_literals) && __cpp_unicode_literals >= 200710
#    define IUTEST_HAS_CHAR16_T     1
#  elif defined(__clang__)
#    if __has_feature(cxx_unicode_literals)
#      define IUTEST_HAS_CHAR16_T   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CHAR16_T   1
#    endif
#  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(__cpp_unicode_characters) && __cpp_unicode_characters >= 200704 && defined(__cpp_unicode_literals) && __cpp_unicode_literals >= 200710
#    define IUTEST_HAS_CHAR32_T 1
#  elif defined(__clang__)
#    if __has_feature(cxx_unicode_literals)
#      define IUTEST_HAS_CHAR32_T   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CHAR32_T   1
#    endif
#  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(__cpp_lambdas) && __cpp_lambdas >= 200907
#    define IUTEST_HAS_LAMBDA       1
#  elif defined(__clang__)
#    if __has_feature(cxx_lambdas)
#      define IUTEST_HAS_LAMBDA     1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_LAMBDA     1
#    endif
#  elif defined(_MSC_VER)
#    if   _MSC_VER > 1800
#      define IUTEST_HAS_LAMBDA     1
#    elif _MSC_VER > 1600
#      define IUTEST_HAS_LAMBDA     1
#      define IUTEST_NO_LAMBDA_SEH_SCOPE_RESOLUTION // lambda v1.1 is not supported try/__try scope resolution.
#    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)
     // https://connect.microsoft.com/VisualStudio/feedback/details/809079/torino-compile-error-template-noexcept
#    if _MSC_FULL_VER >= 190022816
#      define IUTEST_HAS_NOEXCEPT   1
#    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

// 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) && !defined(__clang__)
#    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) && (_MSC_VER < 1910)
// 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

// MS extensions

//! 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)
#  if defined(IUTEST_NO_VARIADIC_MACROS)
#    define IUTEST_ANALYSIS_ASSUME(x)       (void)0
#  else
#    define IUTEST_ANALYSIS_ASSUME(...)     (void)0
#  endif
#endif

#if !defined(IUTEST_HAS_MS_CXX_MODULE)
#  if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023506
#    define IUTEST_HAS_MS_CXX_MODULE        1
#  endif
#endif

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

#if defined(IUTEST_MODULE_EXPORT)
#  define IUTEST_CXX_MODULE_EXPORT          export
#else
#  define IUTEST_CXX_MODULE_EXPORT
#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

//! has c++11 attribute [[]]
#if !defined(IUTEST_HAS_ATTRIBUTE)
#  if defined(__cpp_attributes) && __cpp_attributes >= 200809
#    define IUTEST_HAS_ATTRIBUTE    1
#  elif   defined(__clang__)
#    if __has_feature(cxx_attributes)
#      define IUTEST_HAS_ATTRIBUTE  1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_ATTRIBUTE  1
#    endif
#  elif   defined(_MSC_VER)
#    if _MSC_VER > 1800
#      define IUTEST_HAS_ATTRIBUTE  1
#    endif
#  endif
#endif

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

//! has deprecated attribute
#if !defined(IUTEST_HAS_ATTRIBUTE_DEPRECATED)
#  if defined(__has_cpp_attribute)
#    if __has_cpp_attribute(deprecated) >= 201309
#      define IUTEST_HAS_ATTRIBUTE_DEPRECATED   1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_ATTRIBUTE_DEPRECATED   1
#    endif
#  elif   defined(__clang__)
#    if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)
#      define IUTEST_HAS_ATTRIBUTE_DEPRECATED   1
#    endif
#  elif   defined(_MSC_VER)
#    define IUTEST_HAS_ATTRIBUTE_DEPRECATED     IUTEST_HAS_ATTRIBUTE
#  endif
#endif

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

//! deprecated attribute
#if !defined(IUTEST_ATTRIBUTE_DEPRECATED_)
#  if IUTEST_HAS_ATTRIBUTE_DEPRECATED
#    define IUTEST_ATTRIBUTE_DEPRECATED_        [[deprecated]]
#  endif
#endif

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

//! 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 IUTEST_HAS_ATTRIBUTE
#    define IUTEST_ATTRIBUTE_NORETURN_      [[noreturn]]
#  elif   defined(__clang__)
#    if __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

//! init_priority
#if !defined(IUTEST_ATTRIBUTE_INIT_PRIORITY_)
#  if   defined(__clang__)
#    if __has_attribute(init_priority)
#      define IUTEST_ATTRIBUTE_INIT_PRIORITY_(n)    __attribute__((init_priority(n)))
#    endif
#  elif defined(__GNUC__) && !defined(COMPILER_ICC)
#    define IUTEST_ATTRIBUTE_INIT_PRIORITY_(n)      __attribute__((init_priority(n)))
#  endif
#endif

#if !defined(IUTEST_ATTRIBUTE_INIT_PRIORITY_)
#  define IUTEST_ATTRIBUTE_INIT_PRIORITY_(n)
#endif


// workaround
/**
 * @private
 * @{
*/

#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       pragma macros
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2016, 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_SUPPRESS(x)    IUTEST_PRAGMA(warning (suppress: x))
#  define IUTEST_PRAGMA_MSC_WARN_POP()          IUTEST_PRAGMA(warning (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

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

#if defined(__GNUC__)
//#  if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
//#    define IUTEST_PRAGMA_GCC_WARN_DISABLE(x) IUTEST_PRAGMA(GCC diagnostic ignored x)
//#  endif
#  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)
#    define IUTEST_PRAGMA_CLANG_WARN_PUSH       IUTEST_PRAGMA_GCC_WARN_PUSH
#    define IUTEST_PRAGMA_CLANG_WARN_DISABLE    IUTEST_PRAGMA_GCC_WARN_DISABLE
#    define IUTEST_PRAGMA_CLANG_WARN_POP        IUTEST_PRAGMA_GCC_WARN_POP
#  endif
#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

#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

#if   defined(__clang__)
#  define IUTEST_PRAGMA_WARN_PUSH()     IUTEST_PRAGMA_CLANG_WARN_PUSH()
#  define IUTEST_PRAGMA_WARN_POP()      IUTEST_PRAGMA_CLANG_WARN_PUSH()
#  define IUTEST_PRAGMA_WARN_DISABLE(x) IUTEST_PRAGMA_CLANG_WARN_DISABLE(x)
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA_WARN_PUSH()     IUTEST_PRAGMA_GCC_WARN_PUSH()
#  define IUTEST_PRAGMA_WARN_POP()      IUTEST_PRAGMA_GCC_WARN_POP()
#  define IUTEST_PRAGMA_WARN_DISABLE(x) IUTEST_PRAGMA_GCC_WARN_DISABLE(x)
#elif defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_PUSH()     IUTEST_PRAGMA_MSC_WARN_PUSH()
#  define IUTEST_PRAGMA_WARN_POP()      IUTEST_PRAGMA_MSC_WARN_POP()
#  define IUTEST_PRAGMA_WARN_DISABLE(x)
#else
#  define IUTEST_PRAGMA_WARN_PUSH()
#  define IUTEST_PRAGMA_WARN_POP()
#  define IUTEST_PRAGMA_WARN_DISABLE(x)
#endif


// pragma warning xxx
#if defined(_MSC_VER) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
#  if defined(__clang__)
#    define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()   IUTEST_PRAGMA_CLANG_WARN_PUSH() \
                                                            IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wdeprecated-declarations")
#    define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()     IUTEST_PRAGMA_CLANG_WARN_POP()
#  else
#    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()
#  endif
#else
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
#endif

#if defined(__clang__) || defined(__GNUC__)
#  define IUTEST_PRAGMA_UNUSED_LOCAL_TYPEDEFS_WARN_DISABLE_BEGIN()  \
        IUTEST_PRAGMA_WARN_PUSH()                                   \
        IUTEST_PRAGMA_WARN_DISABLE("-Wunused-local-typedefs")
#  define IUTEST_PRAGMA_UNUSED_LOCAL_TYPEDEFS_WARN_DISABLE_END()    \
        IUTEST_PRAGMA_WARN_POP()
#else
#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_MSC_WARN_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_MSC_WARN_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

#if   defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE()
#elif defined(__clang__)
#  if (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ > 0))
#    define IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE()    IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wdangling-else")
#  endif
#elif defined(__GNUC__)
#  if (__GNUC__ > 6)
#    define IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE()  IUTEST_PRAGMA_GCC_WARN_DISABLE("-Wdangling-else")
#  endif
#endif

#if !defined(IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE)
#  define IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE()
#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       preprocessor definition
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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_)    IIUT_PP_TOSTRING_(z_)
#endif
#define IIUT_PP_TOSTRING_(z_)       #z_

#if !defined(IUTEST_PP_CAT)
#  define IUTEST_PP_CAT(a_, b_)     IIUT_PP_CAT_(a_, b_)
#endif
#define IIUT_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)    IIUT_PP_DEC_I(n)
#define IIUT_PP_DEC_I(n)    IIUT_PP_DEC_##n
#define IIUT_PP_DEC_0       nil
#define IIUT_PP_DEC_1       0
#define IIUT_PP_DEC_2       1
#define IIUT_PP_DEC_3       2
#define IIUT_PP_DEC_4       3
#define IIUT_PP_DEC_5       4
#define IIUT_PP_DEC_6       5
#define IIUT_PP_DEC_7       6
#define IIUT_PP_DEC_8       7
#define IIUT_PP_DEC_9       8
#define IIUT_PP_DEC_10      9
#define IIUT_PP_DEC_11      10
#define IIUT_PP_DEC_12      11
#define IIUT_PP_DEC_13      12
#define IIUT_PP_DEC_14      13
#define IIUT_PP_DEC_15      14
#define IIUT_PP_DEC_16      15
#define IIUT_PP_DEC_17      16
#define IIUT_PP_DEC_18      17
#define IIUT_PP_DEC_19      18
#define IIUT_PP_DEC_20      19
#define IIUT_PP_DEC_21      20
#define IIUT_PP_DEC_22      21
#define IIUT_PP_DEC_23      22
#define IIUT_PP_DEC_24      23
#define IIUT_PP_DEC_25      24
#define IIUT_PP_DEC_26      25
#define IIUT_PP_DEC_27      26
#define IIUT_PP_DEC_28      27
#define IIUT_PP_DEC_29      28
#define IIUT_PP_DEC_30      29
#define IIUT_PP_DEC_31      30
#define IIUT_PP_DEC_32      31
#define IIUT_PP_DEC_33      32
#define IIUT_PP_DEC_34      33
#define IIUT_PP_DEC_35      34
#define IIUT_PP_DEC_36      35
#define IIUT_PP_DEC_37      36
#define IIUT_PP_DEC_38      37
#define IIUT_PP_DEC_39      38
#define IIUT_PP_DEC_40      39
#define IIUT_PP_DEC_41      40
#define IIUT_PP_DEC_42      41
#define IIUT_PP_DEC_43      42
#define IIUT_PP_DEC_44      43
#define IIUT_PP_DEC_45      44
#define IIUT_PP_DEC_46      45
#define IIUT_PP_DEC_47      46
#define IIUT_PP_DEC_48      47
#define IIUT_PP_DEC_49      48
#define IIUT_PP_DEC_50      49
#define IIUT_PP_DEC_51      50
#define IIUT_PP_DEC_52      51
#define IIUT_PP_DEC_53      52
#define IIUT_PP_DEC_54      53
#define IIUT_PP_DEC_55      54
#define IIUT_PP_DEC_56      55
#define IIUT_PP_DEC_57      56
#define IIUT_PP_DEC_58      57
#define IIUT_PP_DEC_59      58
#define IIUT_PP_DEC_60      59
#define IIUT_PP_DEC_61      60
#define IIUT_PP_DEC_62      61
#define IIUT_PP_DEC_63      62
#define IIUT_PP_DEC_64      63
#define IIUT_PP_DEC_65      64
#define IIUT_PP_DEC_66      65
#define IIUT_PP_DEC_67      66
#define IIUT_PP_DEC_68      67
#define IIUT_PP_DEC_69      68
#define IIUT_PP_DEC_70      69
#define IIUT_PP_DEC_71      70
#define IIUT_PP_DEC_72      71
#define IIUT_PP_DEC_73      72
#define IIUT_PP_DEC_74      73
#define IIUT_PP_DEC_75      74
#define IIUT_PP_DEC_76      75
#define IIUT_PP_DEC_77      76
#define IIUT_PP_DEC_78      77
#define IIUT_PP_DEC_79      78
#define IIUT_PP_DEC_80      79
#define IIUT_PP_DEC_81      80
#define IIUT_PP_DEC_82      81
#define IIUT_PP_DEC_83      82
#define IIUT_PP_DEC_84      83
#define IIUT_PP_DEC_85      84
#define IIUT_PP_DEC_86      85
#define IIUT_PP_DEC_87      86
#define IIUT_PP_DEC_88      87
#define IIUT_PP_DEC_89      88
#define IIUT_PP_DEC_90      89
#define IIUT_PP_DEC_91      90
#define IIUT_PP_DEC_92      91
#define IIUT_PP_DEC_93      92
#define IIUT_PP_DEC_94      93
#define IIUT_PP_DEC_95      94
#define IIUT_PP_DEC_96      95
#define IIUT_PP_DEC_97      96
#define IIUT_PP_DEC_98      97
#define IIUT_PP_DEC_99      98
#define IIUT_PP_DEC_100     99

// INC
#define IUTEST_PP_INC(n)    IIUT_PP_INC_I(n)
#define IIUT_PP_INC_I(n)    IIUT_PP_INC_##n
#define IIUT_PP_INC_0       1
#define IIUT_PP_INC_1       2
#define IIUT_PP_INC_2       3
#define IIUT_PP_INC_3       4
#define IIUT_PP_INC_4       5
#define IIUT_PP_INC_5       6
#define IIUT_PP_INC_6       7
#define IIUT_PP_INC_7       8
#define IIUT_PP_INC_8       9
#define IIUT_PP_INC_9       10
#define IIUT_PP_INC_10      11
#define IIUT_PP_INC_11      12
#define IIUT_PP_INC_12      13
#define IIUT_PP_INC_13      14
#define IIUT_PP_INC_14      15
#define IIUT_PP_INC_15      16
#define IIUT_PP_INC_16      17
#define IIUT_PP_INC_17      18
#define IIUT_PP_INC_18      19
#define IIUT_PP_INC_19      20
#define IIUT_PP_INC_20      21
#define IIUT_PP_INC_21      22
#define IIUT_PP_INC_22      23
#define IIUT_PP_INC_23      24
#define IIUT_PP_INC_24      25
#define IIUT_PP_INC_25      26
#define IIUT_PP_INC_26      27
#define IIUT_PP_INC_27      28
#define IIUT_PP_INC_28      29
#define IIUT_PP_INC_29      30
#define IIUT_PP_INC_30      31
#define IIUT_PP_INC_31      32
#define IIUT_PP_INC_32      33
#define IIUT_PP_INC_33      34
#define IIUT_PP_INC_34      35
#define IIUT_PP_INC_35      36
#define IIUT_PP_INC_36      37
#define IIUT_PP_INC_37      38
#define IIUT_PP_INC_38      39
#define IIUT_PP_INC_39      40
#define IIUT_PP_INC_40      41
#define IIUT_PP_INC_41      42
#define IIUT_PP_INC_42      43
#define IIUT_PP_INC_43      44
#define IIUT_PP_INC_44      45
#define IIUT_PP_INC_45      46
#define IIUT_PP_INC_46      47
#define IIUT_PP_INC_47      48
#define IIUT_PP_INC_48      49
#define IIUT_PP_INC_49      50
#define IIUT_PP_INC_50      51
#define IIUT_PP_INC_51      52
#define IIUT_PP_INC_52      53
#define IIUT_PP_INC_53      54
#define IIUT_PP_INC_54      55
#define IIUT_PP_INC_55      56
#define IIUT_PP_INC_56      57
#define IIUT_PP_INC_57      58
#define IIUT_PP_INC_58      59
#define IIUT_PP_INC_59      60
#define IIUT_PP_INC_60      61
#define IIUT_PP_INC_61      62
#define IIUT_PP_INC_62      63
#define IIUT_PP_INC_63      64
#define IIUT_PP_INC_64      65
#define IIUT_PP_INC_65      66
#define IIUT_PP_INC_66      67
#define IIUT_PP_INC_67      68
#define IIUT_PP_INC_68      69
#define IIUT_PP_INC_69      70
#define IIUT_PP_INC_70      71
#define IIUT_PP_INC_71      72
#define IIUT_PP_INC_72      73
#define IIUT_PP_INC_73      74
#define IIUT_PP_INC_74      75
#define IIUT_PP_INC_75      76
#define IIUT_PP_INC_76      77
#define IIUT_PP_INC_77      78
#define IIUT_PP_INC_78      79
#define IIUT_PP_INC_79      80
#define IIUT_PP_INC_80      81
#define IIUT_PP_INC_81      82
#define IIUT_PP_INC_82      83
#define IIUT_PP_INC_83      84
#define IIUT_PP_INC_84      85
#define IIUT_PP_INC_85      86
#define IIUT_PP_INC_86      87
#define IIUT_PP_INC_87      88
#define IIUT_PP_INC_88      89
#define IIUT_PP_INC_89      90
#define IIUT_PP_INC_90      91
#define IIUT_PP_INC_91      92
#define IIUT_PP_INC_92      93
#define IIUT_PP_INC_93      94
#define IIUT_PP_INC_94      95
#define IIUT_PP_INC_95      96
#define IIUT_PP_INC_96      97
#define IIUT_PP_INC_97      98
#define IIUT_PP_INC_98      99
#define IIUT_PP_INC_99      100
#define IIUT_PP_INC_100     nil

// REPEAT
#define IUTEST_PP_LIMIT_REPEAT  50

#define IIUT_PP_REPEAT_PARAMS_MACRO_(i, param)  param
#define IIUT_PP_REPEAT_PARAMS_MACRO_IN_BINARY_(i, param1, param2)   param2(i, param1)

#define IUTEST_PP_REPEAT_PARAMS(n, param)   IUTEST_PP_REPEAT(n, IIUT_PP_REPEAT_PARAMS_MACRO_, param)
#define IUTEST_PP_REPEAT(n, m, param)       IUTEST_PP_REPEAT_BINARY(n, IIUT_PP_REPEAT_PARAMS_MACRO_IN_BINARY_, param, m)

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

#define IUTEST_PP_REPEAT_BINARY_PARAMS(n, param1, param2)   IUTEST_PP_REPEAT_BINARY(n, IIUT_PP_REPEAT_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_REPEAT_BINARY(n, m, param1, param2)       IIUT_PP_REPEAT_BINARY_PARAMS_I(n, m, param1, param2)

#define IIUT_PP_REPEAT_BINARY_PARAMS_I(n, m, p1, p2)    IUTEST_PP_CAT(IIUT_PP_REPEAT_I_, IUTEST_PP_DEC(n))(0, m, p1, p2)

#define IIUT_PP_REPEAT_I_nil(i, m, p1, p2)
#define IIUT_PP_REPEAT_I_0( i, m, p1, p2)       m(i, p1, p2)
#define IIUT_PP_REPEAT_I_1( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_2( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_3( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_4( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_5( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_6( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_7( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_8( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_9( i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_10(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_11(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_12(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_13(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_14(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_15(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_16(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_17(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_18(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_19(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_20(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_21(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_22(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_23(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_24(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_25(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_26(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_27(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_28(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_29(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_30(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_31(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_32(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_33(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_34(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_35(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_36(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_37(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_38(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_39(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_40(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_41(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_42(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_43(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_44(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_45(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_46(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_47(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_48(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_49(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_REPEAT_I_50(i, m, p1, p2)       m(i, p1, p2) IIUT_PP_REPEAT_I_49(IUTEST_PP_INC(i), m, p1, p2)

// ENUM
#define IUTEST_PP_LIMIT_ENUM    50

#define IIUT_PP_ENUM_PARAMS_MACRO_(i, param)    IUTEST_PP_CAT(param, i)
#define IIUT_PP_ENUM_PARAMS_MACRO_IN_BINARY_(i, param1, param2) param2(i, param1)

#define IUTEST_PP_ENUM_PARAMS(n, param)         IUTEST_PP_ENUM(n, IIUT_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM(n, m, param)             IUTEST_PP_ENUM_BINARY(n, IIUT_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_ENUM_SHIFTED_PARAMS(n, param) IUTEST_PP_ENUM_SHIFTED(n, IIUT_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM_SHIFTED(n, m, param)     IUTEST_PP_ENUM_SHIFTED_BINARY(n, IIUT_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IIUT_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, IIUT_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_BINARY(n, m, param1, param2)             IIUT_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, IIUT_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_SHIFTED_BINARY(n, m, param1, param2)     IIUT_PP_ENUM_BINARY_PARAMS_I(1, n, m, param1, param2)

#define IIUT_PP_ENUM_BINARY_PARAMS_I(begin, n, m, p1, p2)   IUTEST_PP_CAT(IIUT_PP_ENUM_I_, IUTEST_PP_DEC(n))(begin, m, p1, p2)

#define IIUT_PP_ENUM_I_nil(i, m, p1, p2)
#define IIUT_PP_ENUM_I_0( i, m, p1, p2)         m(i, p1, p2)
#define IIUT_PP_ENUM_I_1( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_2( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_3( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_4( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_5( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_6( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_7( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_8( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_9( i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_10(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_11(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_12(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_13(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_14(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_15(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_16(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_17(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_18(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_19(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_20(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_21(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_22(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_23(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_24(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_25(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_26(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_27(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_28(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_29(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_30(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_31(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_32(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_33(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_34(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_35(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_36(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_37(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_38(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_39(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_40(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_41(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_42(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_43(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_44(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_45(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_46(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_47(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_48(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_49(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IIUT_PP_ENUM_I_50(i, m, p1, p2)         m(i, p1, p2), IIUT_PP_ENUM_I_49(IUTEST_PP_INC(i), m, p1, p2)

// BOOL
#define IUTEST_PP_BOOL(n)   IIUT_PP_BOOL_I(n)
#define IIUT_PP_BOOL_I(n)   IIUT_PP_BOOL_##n
#define IIUT_PP_BOOL_0      0
#define IIUT_PP_BOOL_1      1
#define IIUT_PP_BOOL_2      1
#define IIUT_PP_BOOL_3      1
#define IIUT_PP_BOOL_4      1
#define IIUT_PP_BOOL_5      1
#define IIUT_PP_BOOL_6      1
#define IIUT_PP_BOOL_7      1
#define IIUT_PP_BOOL_8      1
#define IIUT_PP_BOOL_9      1
#define IIUT_PP_BOOL_10     1
#define IIUT_PP_BOOL_11     1
#define IIUT_PP_BOOL_12     1
#define IIUT_PP_BOOL_13     1
#define IIUT_PP_BOOL_14     1
#define IIUT_PP_BOOL_15     1
#define IIUT_PP_BOOL_16     1
#define IIUT_PP_BOOL_17     1
#define IIUT_PP_BOOL_18     1
#define IIUT_PP_BOOL_19     1
#define IIUT_PP_BOOL_20     1
#define IIUT_PP_BOOL_21     1
#define IIUT_PP_BOOL_22     1
#define IIUT_PP_BOOL_23     1
#define IIUT_PP_BOOL_24     1
#define IIUT_PP_BOOL_25     1
#define IIUT_PP_BOOL_26     1
#define IIUT_PP_BOOL_27     1
#define IIUT_PP_BOOL_28     1
#define IIUT_PP_BOOL_29     1
#define IIUT_PP_BOOL_30     1
#define IIUT_PP_BOOL_31     1
#define IIUT_PP_BOOL_32     1
#define IIUT_PP_BOOL_33     1
#define IIUT_PP_BOOL_34     1
#define IIUT_PP_BOOL_35     1
#define IIUT_PP_BOOL_36     1
#define IIUT_PP_BOOL_37     1
#define IIUT_PP_BOOL_38     1
#define IIUT_PP_BOOL_39     1
#define IIUT_PP_BOOL_40     1
#define IIUT_PP_BOOL_41     1
#define IIUT_PP_BOOL_42     1
#define IIUT_PP_BOOL_43     1
#define IIUT_PP_BOOL_44     1
#define IIUT_PP_BOOL_45     1
#define IIUT_PP_BOOL_46     1
#define IIUT_PP_BOOL_47     1
#define IIUT_PP_BOOL_48     1
#define IIUT_PP_BOOL_49     1
#define IIUT_PP_BOOL_50     1
#define IIUT_PP_BOOL_51     1
#define IIUT_PP_BOOL_52     1
#define IIUT_PP_BOOL_53     1
#define IIUT_PP_BOOL_54     1
#define IIUT_PP_BOOL_55     1
#define IIUT_PP_BOOL_56     1
#define IIUT_PP_BOOL_57     1
#define IIUT_PP_BOOL_58     1
#define IIUT_PP_BOOL_59     1
#define IIUT_PP_BOOL_60     1
#define IIUT_PP_BOOL_61     1
#define IIUT_PP_BOOL_62     1
#define IIUT_PP_BOOL_63     1
#define IIUT_PP_BOOL_64     1
#define IIUT_PP_BOOL_65     1
#define IIUT_PP_BOOL_66     1
#define IIUT_PP_BOOL_67     1
#define IIUT_PP_BOOL_68     1
#define IIUT_PP_BOOL_69     1
#define IIUT_PP_BOOL_70     1
#define IIUT_PP_BOOL_71     1
#define IIUT_PP_BOOL_72     1
#define IIUT_PP_BOOL_73     1
#define IIUT_PP_BOOL_74     1
#define IIUT_PP_BOOL_75     1
#define IIUT_PP_BOOL_76     1
#define IIUT_PP_BOOL_77     1
#define IIUT_PP_BOOL_78     1
#define IIUT_PP_BOOL_79     1
#define IIUT_PP_BOOL_80     1
#define IIUT_PP_BOOL_81     1
#define IIUT_PP_BOOL_82     1
#define IIUT_PP_BOOL_83     1
#define IIUT_PP_BOOL_84     1
#define IIUT_PP_BOOL_85     1
#define IIUT_PP_BOOL_86     1
#define IIUT_PP_BOOL_87     1
#define IIUT_PP_BOOL_88     1
#define IIUT_PP_BOOL_89     1
#define IIUT_PP_BOOL_90     1
#define IIUT_PP_BOOL_91     1
#define IIUT_PP_BOOL_92     1
#define IIUT_PP_BOOL_93     1
#define IIUT_PP_BOOL_94     1
#define IIUT_PP_BOOL_95     1
#define IIUT_PP_BOOL_96     1
#define IIUT_PP_BOOL_97     1
#define IIUT_PP_BOOL_98     1
#define IIUT_PP_BOOL_99     1
#define IIUT_PP_BOOL_100    1
#define IIUT_PP_BOOL_101    1
#define IIUT_PP_BOOL_102    1
#define IIUT_PP_BOOL_103    1
#define IIUT_PP_BOOL_104    1
#define IIUT_PP_BOOL_105    1
#define IIUT_PP_BOOL_106    1
#define IIUT_PP_BOOL_107    1
#define IIUT_PP_BOOL_108    1
#define IIUT_PP_BOOL_109    1
#define IIUT_PP_BOOL_110    1
#define IIUT_PP_BOOL_111    1
#define IIUT_PP_BOOL_112    1
#define IIUT_PP_BOOL_113    1
#define IIUT_PP_BOOL_114    1
#define IIUT_PP_BOOL_115    1
#define IIUT_PP_BOOL_116    1
#define IIUT_PP_BOOL_117    1
#define IIUT_PP_BOOL_118    1
#define IIUT_PP_BOOL_119    1
#define IIUT_PP_BOOL_120    1
#define IIUT_PP_BOOL_121    1
#define IIUT_PP_BOOL_122    1
#define IIUT_PP_BOOL_123    1
#define IIUT_PP_BOOL_124    1
#define IIUT_PP_BOOL_125    1
#define IIUT_PP_BOOL_126    1
#define IIUT_PP_BOOL_127    1
#define IIUT_PP_BOOL_128    1
#define IIUT_PP_BOOL_129    1
#define IIUT_PP_BOOL_130    1
#define IIUT_PP_BOOL_131    1
#define IIUT_PP_BOOL_132    1
#define IIUT_PP_BOOL_133    1
#define IIUT_PP_BOOL_134    1
#define IIUT_PP_BOOL_135    1
#define IIUT_PP_BOOL_136    1
#define IIUT_PP_BOOL_137    1
#define IIUT_PP_BOOL_138    1
#define IIUT_PP_BOOL_139    1
#define IIUT_PP_BOOL_140    1
#define IIUT_PP_BOOL_141    1
#define IIUT_PP_BOOL_142    1
#define IIUT_PP_BOOL_143    1
#define IIUT_PP_BOOL_144    1
#define IIUT_PP_BOOL_145    1
#define IIUT_PP_BOOL_146    1
#define IIUT_PP_BOOL_147    1
#define IIUT_PP_BOOL_148    1
#define IIUT_PP_BOOL_149    1
#define IIUT_PP_BOOL_150    1
#define IIUT_PP_BOOL_151    1
#define IIUT_PP_BOOL_152    1
#define IIUT_PP_BOOL_153    1
#define IIUT_PP_BOOL_154    1
#define IIUT_PP_BOOL_155    1
#define IIUT_PP_BOOL_156    1
#define IIUT_PP_BOOL_157    1
#define IIUT_PP_BOOL_158    1
#define IIUT_PP_BOOL_159    1
#define IIUT_PP_BOOL_160    1
#define IIUT_PP_BOOL_161    1
#define IIUT_PP_BOOL_162    1
#define IIUT_PP_BOOL_163    1
#define IIUT_PP_BOOL_164    1
#define IIUT_PP_BOOL_165    1
#define IIUT_PP_BOOL_166    1
#define IIUT_PP_BOOL_167    1
#define IIUT_PP_BOOL_168    1
#define IIUT_PP_BOOL_169    1
#define IIUT_PP_BOOL_170    1
#define IIUT_PP_BOOL_171    1
#define IIUT_PP_BOOL_172    1
#define IIUT_PP_BOOL_173    1
#define IIUT_PP_BOOL_174    1
#define IIUT_PP_BOOL_175    1
#define IIUT_PP_BOOL_176    1
#define IIUT_PP_BOOL_177    1
#define IIUT_PP_BOOL_178    1
#define IIUT_PP_BOOL_179    1
#define IIUT_PP_BOOL_180    1
#define IIUT_PP_BOOL_181    1
#define IIUT_PP_BOOL_182    1
#define IIUT_PP_BOOL_183    1
#define IIUT_PP_BOOL_184    1
#define IIUT_PP_BOOL_185    1
#define IIUT_PP_BOOL_186    1
#define IIUT_PP_BOOL_187    1
#define IIUT_PP_BOOL_188    1
#define IIUT_PP_BOOL_189    1
#define IIUT_PP_BOOL_190    1
#define IIUT_PP_BOOL_191    1
#define IIUT_PP_BOOL_192    1
#define IIUT_PP_BOOL_193    1
#define IIUT_PP_BOOL_194    1
#define IIUT_PP_BOOL_195    1
#define IIUT_PP_BOOL_196    1
#define IIUT_PP_BOOL_197    1
#define IIUT_PP_BOOL_198    1
#define IIUT_PP_BOOL_199    1
#define IIUT_PP_BOOL_200    1
#define IIUT_PP_BOOL_201    1
#define IIUT_PP_BOOL_202    1
#define IIUT_PP_BOOL_203    1
#define IIUT_PP_BOOL_204    1
#define IIUT_PP_BOOL_205    1
#define IIUT_PP_BOOL_206    1
#define IIUT_PP_BOOL_207    1
#define IIUT_PP_BOOL_208    1
#define IIUT_PP_BOOL_209    1
#define IIUT_PP_BOOL_210    1
#define IIUT_PP_BOOL_211    1
#define IIUT_PP_BOOL_212    1
#define IIUT_PP_BOOL_213    1
#define IIUT_PP_BOOL_214    1
#define IIUT_PP_BOOL_215    1
#define IIUT_PP_BOOL_216    1
#define IIUT_PP_BOOL_217    1
#define IIUT_PP_BOOL_218    1
#define IIUT_PP_BOOL_219    1
#define IIUT_PP_BOOL_220    1
#define IIUT_PP_BOOL_221    1
#define IIUT_PP_BOOL_222    1
#define IIUT_PP_BOOL_223    1
#define IIUT_PP_BOOL_224    1
#define IIUT_PP_BOOL_225    1
#define IIUT_PP_BOOL_226    1
#define IIUT_PP_BOOL_227    1
#define IIUT_PP_BOOL_228    1
#define IIUT_PP_BOOL_229    1
#define IIUT_PP_BOOL_230    1
#define IIUT_PP_BOOL_231    1
#define IIUT_PP_BOOL_232    1
#define IIUT_PP_BOOL_233    1
#define IIUT_PP_BOOL_234    1
#define IIUT_PP_BOOL_235    1
#define IIUT_PP_BOOL_236    1
#define IIUT_PP_BOOL_237    1
#define IIUT_PP_BOOL_238    1
#define IIUT_PP_BOOL_239    1
#define IIUT_PP_BOOL_240    1
#define IIUT_PP_BOOL_241    1
#define IIUT_PP_BOOL_242    1
#define IIUT_PP_BOOL_243    1
#define IIUT_PP_BOOL_244    1
#define IIUT_PP_BOOL_245    1
#define IIUT_PP_BOOL_246    1
#define IIUT_PP_BOOL_247    1
#define IIUT_PP_BOOL_248    1
#define IIUT_PP_BOOL_249    1
#define IIUT_PP_BOOL_250    1
#define IIUT_PP_BOOL_251    1
#define IIUT_PP_BOOL_252    1
#define IIUT_PP_BOOL_253    1
#define IIUT_PP_BOOL_254    1
#define IIUT_PP_BOOL_255    1

// IF
#define IUTEST_PP_IF(cond, t, f)    IIUT_PP_IF_I(IUTEST_PP_BOOL(cond), t, f)
#define IIUT_PP_IF_I(cond, t, f)    IUTEST_PP_CAT(IIUT_PP_IF_, cond)(t, f)
#define IIUT_PP_IF_0(t, f)          f
#define IIUT_PP_IF_1(t, f)          t

// IS EMPTY
#define IUTEST_PP_IS_EMPTY(x)       IIUT_PP_IS_EMPTY_I(x IIUT_PP_EMPTY_TAG)
#define IIUT_PP_IS_EMPTY_I(x)       IIUT_PP_IS_EMPTY_I_( IUTEST_PP_CAT(IIUT_PP_EMPTY_TAG_, x)() )
#define IIUT_PP_IS_EMPTY_I_(x)      IIUT_PP_IS_EMPTY_II((x))
#define IIUT_PP_IS_EMPTY_II(x)      IIUT_PP_IS_EMPTY_II_ x
#define IIUT_PP_IS_EMPTY_II_(a, b)  b

#define IUTEST_PP_EMPTY()
#define IIUT_PP_EMPTY_TAG() , 0
#define IIUT_PP_EMPTY_TAG_IIUT_PP_EMPTY_TAG     1, 1 IUTEST_PP_EMPTY

// IDENTITY
#define IUTEST_PP_IDENTITY(x)       x IUTEST_PP_EMPTY

#if !defined(IUTEST_NO_VARIADIC_MACROS)

#if !defined(IUTEST_PP_VA_CAT)

#define IUTEST_PP_VA_CAT(a, ...)    IIUT_PP_VA_CAT_I(a, __VA_ARGS__)
#define IIUT_PP_VA_CAT_I(a, ...)    a ## __VA_ARGS__

#endif

#if defined(_MSC_VER)
#define IIUT_PP_VD_CAT(a, b)            IIUT_PP_VD_CAT_I(a, b)
#define IIUT_PP_VD_CAT_I(a, b)          IIUT_PP_VD_CAT_II(a ## b)
#define IIUT_PP_VD_CAT_II(res)          res
#define IIUT_PP_SPLIT(i, ...)           IIUT_PP_VD_CAT(IIUT_PP_VA_CAT_I(IIUT_PP_SPLIT_, i)(__VA_ARGS__), IUTEST_PP_EMPTY())
#define IIUT_PP_IS_BEGIN_PARENS_C(...)  1 1
#else
#define IIUT_PP_SPLIT(i, ...)           IIUT_PP_VA_CAT_I(IIUT_PP_SPLIT_, i)(__VA_ARGS__)
#define IIUT_PP_IS_BEGIN_PARENS_C(...)  1
#endif
#define IIUT_PP_SPLIT_0(a, ...) a
#define IIUT_PP_SPLIT_1(a, ...) __VA_ARGS__

// IS_BEGIN_PARENS
#define IUTEST_PP_IS_BEGIN_PARENS(...)                  \
    IIUT_PP_SPLIT(0,                                    \
        IUTEST_PP_VA_CAT( IIUT_PP_IS_BEGIN_PARENS_R_    \
            , IIUT_PP_IS_BEGIN_PARENS_C __VA_ARGS__ ) )

#define IIUT_PP_IS_BEGIN_PARENS_R_1     1,

#define IIUT_PP_IS_BEGIN_PARENS_R_IIUT_PP_IS_BEGIN_PARENS_C 0,

#endif

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_stdlib.hpp
 * @brief       stdlib
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2017, 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 <string.h>
#  include <stdlib.h>
#  include <cstdio>
#  define __STRICT_ANSI__
#endif
#include <cstdlib>

//======================================================================
// define
#if   defined(__GLIBCPP__) || defined(__GLIBCXX__)

// libstdc++
#if   defined(__clang__)
#  if __has_include(<experimental/any>)
#    define IUTEST_LIBSTDCXX_VERSION    50100
#  elif __has_include(<shared_mutex>)
#    define IUTEST_LIBSTDCXX_VERSION    40900
#  elif __has_include(<ext/cmath>)
#    define IUTEST_LIBSTDCXX_VERSION    40800
#  elif   __has_include(<scoped_allocator>)
#    define IUTEST_LIBSTDCXX_VERSION    40700
#  elif __has_include(<typeindex>)
#    define IUTEST_LIBSTDCXX_VERSION    40600
#  elif __has_include(<future>)
#    define IUTEST_LIBSTDCXX_VERSION    40500
#  elif __has_include(<ratio>)
#    define IUTEST_LIBSTDCXX_VERSION    40400
#  elif __has_include(<array>)
#    define IUTEST_LIBSTDCXX_VERSION    40300
#  endif
#elif defined(__GNUC__)
#  define IUTEST_LIBSTDCXX_VERSION      (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
#endif

#if IUTEST_HAS_CXX11
#  if IUTEST_LIBSTDCXX_VERSION >= 50100
#    if !defined(IUTEST_HAS_CXX_HDR_CODECVT)
#      define IUTEST_HAS_CXX_HDR_CODECVT  1
#    endif
#  endif
#  if IUTEST_LIBSTDCXX_VERSION >= 40900
#    if !defined(IUTEST_HAS_CXX_HDR_REGEX)
#      define IUTEST_HAS_CXX_HDR_REGEX    1
#    endif
#  endif
#  if IUTEST_LIBSTDCXX_VERSION >= 40700
#    if !defined(IUTEST_HAS_STD_EMPLACE)
#      define IUTEST_HAS_STD_EMPLACE      1
#    endif
#    if !defined(IUTEST_HAS_CXX_HDR_CHRONO)
#      define IUTEST_HAS_CXX_HDR_CHRONO   1
#    endif
#  endif
#  if IUTEST_LIBSTDCXX_VERSION >= 40600
#    if !defined(IUTEST_HAS_STD_BEGIN_END)
#      define IUTEST_HAS_STD_BEGIN_END    1
#    endif
#  endif
#  if IUTEST_LIBSTDCXX_VERSION >= 40500
#    if !defined(IUTEST_HAS_STD_DECLVAL)
#      define IUTEST_HAS_STD_DECLVAL      1
#    endif
#    if !defined(IUTEST_HAS_CXX_HDR_RANDOM)
#      define IUTEST_HAS_CXX_HDR_RANDOM   1
#    endif
#    if !defined(IUTEST_HAS_CXX_HDR_CSTDINT)
#      define IUTEST_HAS_CXX_HDR_CSTDINT  1
#    endif
#  endif
#  if IUTEST_LIBSTDCXX_VERSION >= 40300
#    if !defined(IUTEST_HAS_CXX_HDR_ARRAY)
#      define IUTEST_HAS_CXX_HDR_ARRAY    1
#    endif
#  endif
#  if defined(_GLIBCXX_HAVE_QUICK_EXIT) && defined(_GLIBCXX_HAVE_AT_QUICK_EXIT)
#    if !defined(IUTEST_HAS_STD_QUICK_EXIT)
#      define IUTEST_HAS_STD_QUICK_EXIT   1
#    endif
#  endif
#  if defined(__has_include)
#    if !defined(IUTEST_HAS_CXX_HDR_CUCHAR) && __has_include( <cuchar> )
#      if defined(_GLIBCXX_USE_C11_UCHAR_CXX11) && _GLIBCXX_USE_C11_UCHAR_CXX11
#        define IUTEST_HAS_CXX_HDR_CUCHAR   1
#      endif
#    endif
#  endif
#endif

// tuple
#if   IUTEST_HAS_VARIADIC_TEMPLATES
#  if !defined(IUTEST_HAS_STD_TUPLE)
#    define IUTEST_HAS_STD_TUPLE          1
#  endif
#elif (!defined(__CUDACC__) && !defined(__ARMCC_VERSION) && (IUTEST_LIBSTDCXX_VERSION >= 40000))
#  if !defined(IUTEST_HAS_TR1_TUPLE)
#    define IUTEST_HAS_TR1_TUPLE          1
#  endif
#endif

#if !defined(IUTEST_HAS_HDR_CXXABI)
#  if   defined(__has_include)
#    if __has_include( <cxxabi.h> )
#      define IUTEST_HAS_HDR_CXXABI       1
#    endif
#  else
#    define IUTEST_HAS_HDR_CXXABI         1
#  endif
#endif

#elif defined(_LIBCPP_VERSION)

// libc++
#if IUTEST_HAS_CXX11
#  if !defined(IUTEST_HAS_STD_BEGIN_END)
#    define IUTEST_HAS_STD_BEGIN_END      1
#  endif
#  if !defined(IUTEST_HAS_STD_DECLVAL)
#    define IUTEST_HAS_STD_DECLVAL        1
#  endif
#  if !defined(IUTEST_HAS_STD_EMPLACE)
#    define IUTEST_HAS_STD_EMPLACE        1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CHRONO)
#    define IUTEST_HAS_CXX_HDR_CHRONO     1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_REGEX)
#    define IUTEST_HAS_CXX_HDR_REGEX      1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_RANDOM)
#    define IUTEST_HAS_CXX_HDR_RANDOM     1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CODECVT)
#    define IUTEST_HAS_CXX_HDR_CODECVT    1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CSTDINT)
#    define IUTEST_HAS_CXX_HDR_CSTDINT    1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_ARRAY)
#    define IUTEST_HAS_CXX_HDR_ARRAY      1
#  endif
#  if !defined(IUTEST_HAS_STD_QUICK_EXIT) && defined(_LIBCPP_HAS_QUICK_EXIT)
#    define IUTEST_HAS_STD_QUICK_EXIT     1
#  endif
#  if   defined(__has_include)
#    if !defined(IUTEST_HAS_CXX_HDR_CUCHAR) && __has_include( <cuchar> )
#      define IUTEST_HAS_CXX_HDR_CUCHAR   1
#    endif
#  endif
#endif

#if _LIBCPP_VERSION >= 1001
#  if !defined(IUTEST_HAS_STD_BEGIN_END)
#    define IUTEST_HAS_STD_BEGIN_END      1
#  endif
#endif

// tuple
#if   IUTEST_HAS_VARIADIC_TEMPLATES
#  if !defined(IUTEST_HAS_STD_TUPLE)
#    define IUTEST_HAS_STD_TUPLE          1
#  endif
#elif defined(__has_include)
#  if !defined(IUTEST_HAS_TR1_TUPLE) && __has_include( <tr1/tuple> )
#    define IUTEST_HAS_TR1_TUPLE        1
#  endif
#endif

#if   defined(__has_include)
#  if !defined(IUTEST_HAS_HDR_CXXABI) && __has_include( <cxxabi.h> )
#    define IUTEST_HAS_HDR_CXXABI       1
#  endif
#endif

#elif defined(_MSC_VER) && defined(_MSC_FULL_VER)

// Visual C++

#if _MSC_VER >= 1600
#  if !defined(IUTEST_HAS_CXX_HDR_ARRAY)
#    define IUTEST_HAS_CXX_HDR_ARRAY      1
#  endif
#endif

#if _MSC_VER >= 1700
#  if !defined(IUTEST_HAS_STD_BEGIN_END)
#    define IUTEST_HAS_STD_BEGIN_END      1
#  endif
#  if !defined(IUTEST_HAS_STD_DECLVAL)
#    define IUTEST_HAS_STD_DECLVAL        IUTEST_HAS_DECLTYPE
#  endif
#  if !defined(IUTEST_HAS_STD_EMPLACE)
#    define IUTEST_HAS_STD_EMPLACE        1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_REGEX)
#    define IUTEST_HAS_CXX_HDR_REGEX      1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_RANDOM)
#    define IUTEST_HAS_CXX_HDR_RANDOM     1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CODECVT)
#    define IUTEST_HAS_CXX_HDR_CODECVT    1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CSTDINT)
#    define IUTEST_HAS_CXX_HDR_CSTDINT    1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CHRONO) && _MSC_FULL_VER != 190023725
#    define IUTEST_HAS_CXX_HDR_CHRONO   1
#  endif
#endif

#if _MSC_VER >= 1900
#  if !defined(IUTEST_HAS_STD_QUICK_EXIT)
#    define IUTEST_HAS_STD_QUICK_EXIT     1
#  endif
#  if !defined(IUTEST_HAS_CXX_HDR_CUCHAR)
#    define IUTEST_HAS_CXX_HDR_CUCHAR     1
#  endif
#endif

// tuple
#if (_MSC_VER > 1700) || (_MSC_VER == 1700 && _VARIADIC_MAX >= 9)
#  if !defined(IUTEST_HAS_STD_TUPLE)
#    define IUTEST_HAS_STD_TUPLE          1
#  endif
#elif (_MSC_VER >= 1500) && (_MSC_VER < 1700) && (_MSC_FULL_VER > 150021022)
#  if !defined(IUTEST_HAS_TR1_TUPLE)
#    define IUTEST_HAS_TR1_TUPLE          1
#  endif
#endif

#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)

// stlport

#endif

#if defined(__has_include)
#  if defined(IUTEST_HAS_CXX_HDR_CODECVT) && IUTEST_HAS_CXX_HDR_CODECVT
#    if !__has_include( <codecvt> )
#      undef IUTEST_HAS_CXX_HDR_CODECVT
#    endif
#  endif
#endif

//! has std::begin,std::end
#if !defined(IUTEST_HAS_STD_BEGIN_END)
#  define IUTEST_HAS_STD_BEGIN_END      0
#endif
//! has std::declval
#if !defined(IUTEST_HAS_STD_DECLVAL)
#  define IUTEST_HAS_STD_DECLVAL        0
#endif
//! use external include tr1::tuple
#if !defined(IUTEST_USE_EXTERNAL_TR1_TUPLE)
#  define IUTEST_USE_EXTERNAL_TR1_TUPLE 0
#endif
//! use external include std::tuple
#ifndef IUTEST_USE_EXTERNAL_STD_TUPLE
#  define IUTEST_USE_EXTERNAL_STD_TUPLE 0
#endif
//! has ::std::tuple
#if !defined(IUTEST_HAS_STD_TUPLE)
#  define IUTEST_HAS_STD_TUPLE          0
#endif
//! has ::std::tr1::tuple
#if !defined(IUTEST_HAS_TR1_TUPLE)
#  define IUTEST_HAS_TR1_TUPLE          0
#endif
//! has tuple
#if IUTEST_HAS_STD_TUPLE || IUTEST_HAS_TR1_TUPLE || IUTEST_USE_EXTERNAL_TR1_TUPLE || IUTEST_USE_EXTERNAL_STD_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
//! has chrono header
#if !defined(IUTEST_HAS_CXX_HDR_CHRONO)
#  define IUTEST_HAS_CXX_HDR_CHRONO     0
#endif
//! has regex header
#if !defined(IUTEST_HAS_CXX_HDR_REGEX)
#  define IUTEST_HAS_CXX_HDR_REGEX      0
#endif
//! has random header
#if !defined(IUTEST_HAS_CXX_HDR_RANDOM)
#  define IUTEST_HAS_CXX_HDR_RANDOM     0
#endif
//! has codecvt header
#if !defined(IUTEST_HAS_CXX_HDR_CODECVT)
#  define IUTEST_HAS_CXX_HDR_CODECVT    0
#endif
//! has cstdint header
#if !defined(IUTEST_HAS_CXX_HDR_CSTDINT)
#  define IUTEST_HAS_CXX_HDR_CSTDINT    0
#endif
//! has array header
#if !defined(IUTEST_HAS_CXX_HDR_ARRAY)
#  define IUTEST_HAS_CXX_HDR_ARRAY      0
#endif
//! has emplace
#if !defined(IUTEST_HAS_STD_EMPLACE)
#  define IUTEST_HAS_STD_EMPLACE        0
#endif
//! has quick_exit
#if !defined(IUTEST_HAS_STD_QUICK_EXIT)
#  define IUTEST_HAS_STD_QUICK_EXIT     0
#endif
//! has cxxabi header
#if !defined(IUTEST_HAS_HDR_CXXABI)
#  define IUTEST_HAS_HDR_CXXABI         0
#endif
//! has cuchar
#if !defined(IUTEST_HAS_CXX_HDR_CUCHAR)
#  define IUTEST_HAS_CXX_HDR_CUCHAR     0
#endif

//======================================================================
// include
#if IUTEST_HAS_CXX_HDR_CSTDINT
#  include <cstdint>
#endif
#include <iterator>

//======================================================================
// declare

//! std::sto* が使用可能かどうか
#if !defined(IUTEST_HAS_STD_STR_TO_VALUE)
#  if IUTEST_HAS_CXX11
#    if defined(IUTEST_OS_WINDOWS_MINGW)
#      if defined(__MINGW64__) && (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
#        define IUTEST_HAS_STD_STR_TO_VALUE 1
#      endif
#    else
#      define IUTEST_HAS_STD_STR_TO_VALUE   1
#    endif
#  endif
#endif

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

//! using begin,end
#if !defined(IUTEST_USING_BEGIN_END)
#  if IUTEST_HAS_STD_BEGIN_END
#    define IUTEST_USING_BEGIN_END()    \
    using ::std::begin; using ::std::end
#  else
#    define IUTEST_USING_BEGIN_END()    \
    using ::iutest::detail::cxx::begin; using ::iutest::detail::cxx::end
#  endif
#endif

namespace iutest {
namespace detail {
namespace cxx
{

#if IUTEST_HAS_STD_BEGIN_END

using ::std::begin;
using ::std::end;

#else

template<typename T> typename T::iterator begin(T& x) { return x.begin(); }
template<typename T> typename T::iterator end  (T& x) { return x.end(); }

template<typename T> typename T::const_iterator begin(const T& x) { return x.begin(); }
template<typename T> typename T::const_iterator end  (const T& x) { return x.end(); }

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
template<typename T, size_t SIZE> T* begin(T (&x)[SIZE]) { return &x[0]; }
template<typename T, size_t SIZE> T* end  (T (&x)[SIZE]) { return begin(x) + SIZE; }

template<typename T, size_t SIZE> const T* begin(const T (&x)[SIZE]) { return &x[0]; }
template<typename T, size_t SIZE> const T* end  (const T (&x)[SIZE]) { return begin(x) + SIZE; }
#endif

#endif

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

#if IUTEST_HAS_TUPLE
#if !IUTEST_USE_EXTERNAL_STD_TUPLE && !IUTEST_USE_EXTERNAL_TR1_TUPLE
#  if   IUTEST_HAS_STD_TUPLE
#    include <tuple>
#  elif IUTEST_HAS_TR1_TUPLE
#    if (defined(__GNUC__) && (__GNUC__ >= 4))
#      include <tr1/tuple>
#    else
#      include <tuple>
#    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);
    }
};

}   // end of namespace detail

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

}   // end of namespace tuples

using tuples::tuple;
using tuples::tuple_size;
using tuples::tuple_element;
using tuples::tuple_foreach;
using tuples::make_tuple;
using tuples::get;

}   // end of namespace iutest

#endif

//! has sys/time.h header
#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

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

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


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

namespace iutest {
namespace detail
{

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


template<>
struct type_least_t<1>
{
#if defined(INT_LEAST8_MIN)
    typedef int_least8_t        Int;
    typedef uint_least8_t       UInt;
#else
    typedef char                Int;
    typedef unsigned char       UInt;
#endif
};


template<>
struct type_least_t<2>
{
#if defined(INT_LEAST16_MIN)
    typedef int_least16_t       Int;
    typedef uint_least16_t      UInt;
#else
    typedef short               Int;
    typedef unsigned short      UInt;
#endif
};


template<>
struct type_least_t<4>
{
#if defined(INT_LEAST32_MIN)
    typedef int_least32_t       Int;
    typedef uint_least32_t      UInt;
#else
    typedef int                 Int;
    typedef unsigned int        UInt;
#endif
};


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

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


template<>
struct type_fit_t<1>
{
#if defined(INT8_MIN)
    typedef int8_t              Int;
    typedef uint8_t             UInt;
#else
    typedef char                Int;
    typedef unsigned char       UInt;
#endif
};


template<>
struct type_fit_t<2>
{
#if defined(INT16_MIN)
    typedef int16_t             Int;
    typedef uint16_t            UInt;
#else
    typedef short               Int;
    typedef unsigned short      UInt;
#endif
};


template<>
struct type_fit_t<4>
{
#if defined(INT32_MIN)
    typedef int32_t             Int;
    typedef uint32_t            UInt;
#else
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
private:
    template<typename T, typename F, bool b>
    struct impl { typedef T type; };
    template<typename T, typename F>
    struct impl<T, F, false> { typedef F type; };

public:
    typedef impl<long, int
        , sizeof(int) != 4 && sizeof(long) == 4>::type Int;
    typedef impl<unsigned long, unsigned int
        , sizeof(int) != 4 && sizeof(long) == 4>::type UInt;
#else
    typedef int                 Int;
    typedef unsigned int        UInt;
#endif
#endif
};


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

//======================================================================
// 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-2017, 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   式アサーションで算術演算子の展開をサポートするかどうか
 * @deprecated
*/
#  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_CSVPARAMS)
//! ::iutest::CSV が使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST && IUTEST_HAS_STRINGSTREAM
#    define IUTEST_HAS_CSVPARAMS    1
#  else
#    define IUTEST_HAS_CSVPARAMS    0
#  endif
#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::matchers::ElementsAre matcher が使用可能かどうか
#  if IUTEST_HAS_TUPLE && !defined(IUTEST_NO_SFINAE)
#    define IUTEST_HAS_MATCHER_ELEMENTSARE      IUTEST_HAS_MATCHERS
#  else
#    define IUTEST_HAS_MATCHER_ELEMENTSARE      0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD)
//! ::iutest::matchers::ElementsAreArrayForward matcher が使用可能かどうか
#  if IUTEST_HAS_TUPLE && !defined(IUTEST_NO_SFINAE)
#    define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD  IUTEST_HAS_MATCHERS
#  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::matchers::MatchesRegex, ::iutest::matchers::ContainsRegex matcher が使用可能かどうか
#  if IUTEST_HAS_CXX_HDR_REGEX && IUTEST_HAS_REGEX
#    define IUTEST_HAS_MATCHER_REGEX    IUTEST_HAS_MATCHERS
#  else
#    define IUTEST_HAS_MATCHER_REGEX    0
#  endif
#endif

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

#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 !IUTEST_HAS_EXCEPTIONS && IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#  undef IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#  define IUTEST_USE_THROW_ON_ASSERTION_FAILURE         0
#endif

#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_CATCH_SEH_EXCEPTION_ASSERTION)
//! 例外アサーションで SEH をキャッチ可能かどうか
#  if IUTEST_HAS_LAMBDA_STATEMENTS && IUTEST_HAS_SEH
#    define IUTEST_HAS_CATCH_SEH_EXCEPTION_ASSERTION  1
#  else
#    define IUTEST_HAS_CATCH_SEH_EXCEPTION_ASSERTION  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_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_MEMBER_FUNCTION
#    define IUTEST_HAS_PEEP_FUNC    IUTEST_HAS_PEEP
#  else
#    define IUTEST_HAS_PEEP_FUNC    0
#  endif
#endif

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

#if !defined(IUTEST_HAS_PEEP_CLASS)
//! private メンバー関数へのアクセスが可能かどうか
#  if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#    define IUTEST_HAS_PEEP_CLASS   IUTEST_HAS_PEEP
#  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_TESTFIXTURE_ALIAS_BY_TUPLE)
//! テスト名の別名指定の簡易記法が可能かどうか
#  define IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE IUTEST_HAS_TESTNAME_ALIAS
#endif

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

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

#if !defined(IUTEST_TYPED_TEST_APPEND_TYPENAME)
//! @deprecated
#  define IUTEST_TYPED_TEST_APPEND_TYPENAME     0
#endif

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

#if !defined(IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR)
//! 値をパラメータ化したテストのパラメータ名生成が可能かどうか
#  if   !defined(IUTEST_NO_VARIADIC_MACROS)
#    define IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR  1
#  else
#    define IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR  0
#  endif
#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) && (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x501)
#      define IUTEST_HAS_SOCKET 1
#    endif
#  elif defined(IUTEST_OS_CYGWIN) || defined(IUTEST_OS_LINUX)
#    define IUTEST_HAS_SOCKET   1
#  endif
#endif

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

/**
 * @brief   stdout/stderr の StreamBuffer が使用可能かどうか
*/
#if !defined(IUTEST_HAS_STREAM_BUFFER)
#  define IUTEST_HAS_STREAM_BUFFER  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_SETENV    //!< setenv 関数がない場合は定義
#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"
#elif _MSC_VER == 1910
#  define IUTEST_LIB_TOOLSET    "vc141"
#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-2016, 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 <crtdbg.h>
#  include <xlocnum>
#  include <xtree>
#  include <streambuf>
#  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()
{
#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();
    ~MiniDump();

    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-2016, 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()
    : 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()
{
    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
        );
    const pfnMiniDumpWriteDump proc = reinterpret_cast<const 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 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;

}   // end of namespace helper

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

/**
 * @internal
 * @brief   TypeId Generator
*/
inline IUTEST_CXX_CONSTEXPR TypeId GetTestTypeId()
{
    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
    };
};

}   // end of namespace detail

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

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

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

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

    /**
     * @brief   コンストラクタ
    */
    floating_point(const floating_point& 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() const { return m_v.uv; }

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

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

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

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

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

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

public:
#if !defined(_MSC_VER) || _MSC_VER >= 1310
    operator RawType () const   { return m_v.fv; }  //!< cast to RawType
#else
    operator float() const  { return m_v.fv; }
    operator double() const { return m_v.fv; }
#endif
    _Myt&   operator = (RawType f)  { m_v.fv = f; return *this; }   //!< 代入
    _Myt&   operator = (const _Myt& rhs) { m_v.fv = rhs.m_v; return *this; }   //!< 代入

    bool    operator == (const _Myt& rhs) const { return m_v.uv == rhs.m_v.uv; }    //!< 比較

private:
    enum
    {
          kEXP = detail::ieee754_bits<RawType>::EXP
        , kFRAC = detail::ieee754_bits<RawType>::FRAC
        , kMaxUlps = 4
    };

private:
    static UInt norm(UInt v) { return v & kSignMask ? ~v + 1 : v | kSignMask; }

#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_fit_t<4>::Int  Int32;  //!< 32 bit 符号付き整数型
typedef detail::type_fit_t<4>::UInt UInt32; //!< 32 bit 符号なし整数型
typedef detail::type_fit_t<8>::Int  Int64;  //!< 64 bit 符号付き整数型
typedef detail::type_fit_t<8>::UInt UInt64; //!< 64 bit 符号なし整数型

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

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

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

}   // end of namespace iutest

/*
#if IUTEST_HAS_ATTRIBUTE_DEPRECATED
namespace iutest {
namespace detail
{

template<typename T>
struct type_check_t { static const int IUTEST_ATTRIBUTE_DEPRECATED_ value = 0; };

#if IUTEST_HAS_RVALUE_REFS
template<typename T>
int type_check(T&& x) { return 0; }
#else
template<typename T>
int type_check(const T& x) { return 0; }
#endif

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

#if defined(_MSC_VER)
#  if IUTEST_HAS_DECLTYPE
#    define IUTEST_CHECK_TYPE(x)    (void)::iutest::detail::type_check_t< decltype(x) >::value
#  endif
#else
#  define IUTEST_CHECK_TYPE(x)      ::iutest::detail::type_check(x)
#endif

#if !defined(IUTEST_CHECK_TYPE)
#  define IUTEST_CHECK_TYPE(x)      (void)0
#endif

#endif
*/

#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-2017, 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 <wchar.h>
#include <wctype.h>
#include <stdarg.h>
#include <errno.h>
#if defined(IUTEST_OS_CYGWIN)
#include <strings.h>
#endif
#if   IUTEST_HAS_STRINGSTREAM
#  include <sstream>
#elif IUTEST_HAS_STRSTREAM
#  include <strstream>
#endif
#include <string>
#include <cstring>

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(__BORLANDC__)
    return stricmp(str1, str2);
#elif defined(_MSC_VER)
    return _stricmp(str1, str2);
#elif defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MINGW) && !defined(__STRICT_ANSI__)
    return _stricmp(str1, str2);
#elif !defined(__MWERKS__) && !defined(IUTEST_OS_WINDOWS)
    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
}

namespace wrapper
{

inline int iu_vsnprintf(char* dst, size_t size, const char* format, va_list va)
{
    char buffer[4096];
    const int ret = vsprintf(buffer, format, va);
    if( dst != NULL )
    {
        const size_t length = static_cast<size_t>(ret);
        const size_t write = (size <= length) ? size - 1 : length;
        strncpy(dst, buffer, write);
        dst[write] = '\0';
    }
    return ret;
}

} // end of namespace wrapper

/**
 * @internal
 * @brief   vsnprintf
*/
inline int iu_vsnprintf(char* dst, size_t size, const char* format, va_list va)
{
#if   defined(__CYGWIN__) && defined(__STRICT_ANSI__) \
        && (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) && (__cplusplus >= 201103L)
    return wrapper::iu_vsnprintf(dst, size, format, va);
#elif (defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)) && defined(__STRICT_ANSI__)
    return wrapper::iu_vsnprintf(dst, size, format, va);
#else
    if( dst == NULL && size > 0 )
    {
        return -1;
    }
    return vsnprintf(dst, size, format, va);
#endif
}

/**
 * @internal
 * @brief   snprintf
*/
inline int iu_snprintf(char* dst, size_t size, const char* format, ...)
{
    va_list va;
    va_start(va, format);
    const int ret = iu_vsnprintf(dst, size, format, va);
    va_end(va);
    return ret;
}

inline bool IsEmpty(const char* p) { return p == NULL || *p == '\0'; }
inline IUTEST_CXX_CONSTEXPR bool IsSpace(char ch) { return ch == ' ' || ch =='\t'; }
inline const char* NullableString(const char* str) { return str == NULL ? "" : str; }
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 ::std::string StripLeadingSpace(const ::std::string& str)
{
    ::std::string::const_iterator it = str.begin();
    while( it != str.end() && IsSpace(*it) )
    {
        ++it;
    }
    return ::std::string(it, str.end());
}
inline ::std::string StripTrailingSpace(const ::std::string& str)
{
    ::std::string::const_iterator it = str.end()-1;
    while(it != str.begin() && IsSpace(*it))
    {
        --it;
    }
    return ::std::string(str.begin(), it+1);
}
inline ::std::string StripSpace(const ::std::string& str)
{
    ::std::string::const_iterator start = str.begin();
    while( start != str.end() && IsSpace(*start) )
    {
        ++start;
    }
    ::std::string::const_iterator end = str.end()-1;
    while( end != str.begin() && IsSpace(*end) )
    {
        --end;
    }
    return ::std::string(start, end+1);
}

inline bool StringIsBlank(const ::std::string& str)
{
    ::std::string::const_iterator it = str.begin();
    while( it != str.end() )
    {
        const char ch = *it;
        if( !IsSpace(ch) && ch != '\r' && ch != '\n' )
        {
            return false;
        }
        ++it;
    }
    return true;
}

inline void StringReplaceToLF(::std::string& str)
{
    ::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 kN = sizeof(T)*2;
    char buf[kN + 1] = {0};
    for( size_t i=0; i < kN; ++i )
    {
        buf[i] = ToHex(static_cast<unsigned int>((value>>((kN-i-1)*4))));
    }
    buf[kN] = '\0';
    return buf;
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;
}

inline ::std::string StringFormat(const char* format, ...)
{
    size_t n = strlen(format) * 2;
    {
        va_list va;
        va_start(va, format);
        const size_t ret = iu_vsnprintf(NULL, 0, format, va);
        va_end(va);
        if( ret > 0 )
        {
            n = ret;
        }
    }
    for( ;; )
    {
        char* dst = new char[n];
        va_list va;
        va_start(va, format);
        const int written = iu_vsnprintf(dst, n, format, va);
        va_end(va);
        if( written < 0 )
        {
#if defined(EOVERFLOW)
            if( errno == EOVERFLOW )
            {
                break;
            }
#endif
#if defined(E2BIG)
            if( errno == E2BIG )
            {
                break;
            }
#endif
        }
        else if( static_cast<size_t>(written) < n )
        {
            ::std::string s = ::std::string(dst, static_cast<size_t>(written));
            delete[] dst;
            return s;
        }
        delete[] dst;
        n *= 2;
    }
    return "";
}

//======================================================================
// 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()
        : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
    {}
    explicit stlstream(const char* str)
        : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
    {
        *this << str;
    }
    explicit stlstream(const ::std::string& str)
        : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
    {
        *this << str;
    }
public:
    ::std::string str() const
    {
        return const_cast<stlstream*>(this)->str();
    }
    virtual ::std::string str()
    {
        *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 IIUT_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() {}
    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 += static_cast<char>(v);
        return *this;
    }
    inline _Myt& operator<< (unsigned char v)
    {
        s += static_cast<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, IIUT_PP_XCS("%i"), v);
        s += a;
#else
        s += (v ? IIUT_PP_XCS("true") : IIUT_PP_XCS("false"));
#endif
        return *this;
    }
    inline _Myt& operator<< (short v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (unsigned short v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (int v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (unsigned int v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (long v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (unsigned long v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (long long int v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%lld"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (unsigned long long int v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%llu"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (float v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%f"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (double v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%l"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (long double v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%L"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (const void* v)
    {
        _Elem a[64];
        impl::tostring(a, 64, IIUT_PP_XCS("%t"), v);
        s += a;
        return *this;
    }
    inline _Myt& operator<< (const ::std::string& v)
    {
        s += v;
        return *this;
    }
public:
    const string& str() const { return s; }
    void copyfmt(const _Myt&) {}
};

#undef IIUT_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       type traits
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2017, 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 > {};

#if defined(__cpp_lib_bool_constant) && __cpp_lib_bool_constant >= 201505
using ::std::bool_constant;
#else
template<bool B>
struct bool_constant : ::std::integral_constant<bool, B> {};
#endif

#else

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

}   // end of namespace is_pointer_helper

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

}   // end of namespace is_reference_helper

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

}   // end of namespace is_void_helper

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

}   // end of namespace is_const_helper

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

}   // end of namespace is_same_helper

#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];    // NOLINT

    enum { IsClass = sizeof(IsClassHelper<T>(0)) == 1 ? true : false };
public:
    typedef bool_constant<IsClass> type;
};

}   // end of namespace is_class_helper

/**
 * @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();

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

}   // end of namespace is_convertible_helper

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

}   // end of namespace is_base_of_helper

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

}   // end of namespace is_function_pointer_helper

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

}   // end of namespace is_member_function_pointer_helper

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

}   // end of namespace is_member_pointer_helper

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

}   // end of namespace has_equal_to_operator_helper

namespace has_equal_to_operator_impl
{

using namespace has_equal_to_operator_helper;   // NOLINT

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

}   // end of namespace has_equal_to_operator_impl

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

}   // end of namespace has_not_equal_to_operator_helper

namespace has_not_equal_to_operator_impl
{

using namespace has_not_equal_to_operator_helper;   // NOLINT

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

}   // end of namespace has_not_equal_to_operator_impl

/**
 * @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 (*)()>    { typedef R type; };
    template<typename R, typename U>struct impl<R (U::*)()> { typedef R type; };

#define IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(CV)    \
    template<typename R, typename U>struct impl<R (U::*)() 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_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_exception.hpp
 * @brief       iris unit test exception
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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() : ::std::exception() {}
    explicit seh_exception(const char *const& _What) : ::std::exception(_What) {}
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 コード
};

template<typename T>
void seh_passthrough(T func)
{
    _EXCEPTION_POINTERS* ep = NULL;
    __try
    {
        (func)();
    }
    __except( ep = GetExceptionInformation()
        , seh_exception::should_process_through_break_and_cppexceptions(GetExceptionCode()) )
    {
        seh_exception::translator(GetExceptionCode(), ep);
    }
}


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

#endif

#endif

#endif // INCG_IRIS_IUTEST_EXCEPTION_HPP_B73B2E25_97C8_4DFC_BC32_5E53039A1A64_

#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_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

#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() { return true; }

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

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

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

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

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

#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() { return NULL; }

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

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

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

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

    T& operator = (auto_ptr& rhs) { m_ptr = rhs.m_ptr; rhs.m_ptr = NULL; return *this; }

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

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

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

    T* get() const { return m_ptr; }
    T* release()
    {
        T* const p = m_ptr;
        m_ptr = 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 {};
};

}   // end of namespace helper

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   型名の取得
*/
template<typename T>
inline ::std::string GetTypeName()
{
#if IUTEST_HAS_RTTI
    const char* const name = typeid(T).name();

#if IUTEST_HAS_HDR_CXXABI
    using abi::__cxa_demangle;
    int status=1;
    char* const read_name = __cxa_demangle(name, 0, 0, &status);
    ::std::string str = status == 0 ? read_name : name;
    free(read_name);
    return str;
#else
    return name;
#endif

#else
    return "<type>";
#endif
}

#if !IUTEST_HAS_RTTI

#define IIUT_GeTypeNameSpecialization(type) \
    template<>inline ::std::string GetTypeName<type>() { return #type; }    \
    template<>inline ::std::string GetTypeName<type*>() { return #type "*"; }

#define IIUT_GeTypeNameSpecialization2(type)    \
    IIUT_GeTypeNameSpecialization(type)         \
    IIUT_GeTypeNameSpecialization(unsigned type)

IIUT_GeTypeNameSpecialization2(char)    // NOLINT
IIUT_GeTypeNameSpecialization2(short)   // NOLINT
IIUT_GeTypeNameSpecialization2(int)     // NOLINT
IIUT_GeTypeNameSpecialization2(long)    // NOLINT
IIUT_GeTypeNameSpecialization(float)    // NOLINT
IIUT_GeTypeNameSpecialization(double)   // NOLINT
IIUT_GeTypeNameSpecialization(bool)     // NOLINT

#undef IIUT_GeTypeNameSpecialization
#undef IIUT_GeTypeNameSpecialization2

#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

//======================================================================
// define
#if !defined(IUTEST_MAX_PATH)
#  if   defined(MAX_PATH) && MAX_PATH
#    define IUTEST_MAX_PATH MAX_PATH
#  elif defined(PATH_MAX) && PATH_MAX
#    define IUTEST_MAX_PATH PATH_MAX
#  elif defined(FILENAME_MAX) && FILENAME_MAX
#    define IUTEST_MAX_PATH FILENAME_MAX
#  else
#    define IUTEST_MAX_PATH 1024
#  endif
#endif

/**
 * @brief   ログメッセージストリーム
*/
#define IUTEST_LOG_(level)          \
    ::iutest::detail::IUTestLog(    \
        ::iutest::detail::IUTestLog::LOG_##level, __FILE__, __LINE__).GetStream()

/**
 * @brief   内部エラーチェック
*/
#define IUTEST_CHECK_(condition)                \
    IUTEST_AMBIGUOUS_ELSE_BLOCKER_              \
    if( !::iutest::detail::IsTrue(condition) )  \
        IUTEST_LOG_(FATAL) << "Condition " #condition " failed. "

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);
int SetEnv(const char* name, const char* value, int overwrite);

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

void SleepMillisec(unsigned int millisec);

#if defined(IUTEST_OS_WINDOWS_MOBILE)
void Abort();
#else
IUTEST_ATTRIBUTE_NORETURN_ void Abort();
inline void Abort() { 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() IUTEST_CXX_NOEXCEPT_SPEC;

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

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

/**
 * @brief   一番後ろのパスセパレータのアドレスを取得
*/
const char* FindLastPathSeparator(const char* path, size_t length) 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
        , LOG_LEVEL_NUM
    };
public:
    IUTestLog(Level level, const char* file, int line);

    ~IUTestLog();

public:
    iu_stringstream& GetStream() { return m_stream; }

public:
    static int GetCount(Level level) { return GetCountTable().count[level]; }
    static bool HasWarning() { return GetCount(LOG_WARNING) > 0; }
    static bool HasError() { return GetCount(LOG_ERROR) > 0 || GetCount(LOG_FATAL) > 0; }

private:
    struct Count
    {
        int count[LOG_LEVEL_NUM];
    };

    static Count& GetCountTable() { static Count count = { {0} }; return count; }
    static void CountUp(int level);

private:
    const Level kLevel;
    iu_stringstream m_stream;

    IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTestLog);
};

#if IUTEST_HAS_STREAM_BUFFER

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

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

    ~IUStreamBuffer()
    {
        fflush(m_fp);
        setbuf(m_fp, NULL);
    }

    IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

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

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

/**
* @brief    stream capture
*/


#endif

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

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_port.ipp
 * @brief       portable
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, 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");   // NOLINT
    while( tp != NULL )
    {
        detail::PostMessage(pp::Var(tp));
        tp = strtok(NULL, "\n");    // NOLINT
    }
}
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_NO_GETENV) \
    || defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE)
    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_NO_PUTENV) || defined(__STRICT_ANSI__) \
    || defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE)
    IUTEST_UNUSED_VAR(expr);
    return -1;
#elif defined(IUTEST_OS_WINDOWS)
    return _putenv(expr);
#else
    return putenv(const_cast<char*>(expr));
#endif
}

IUTEST_IPP_INLINE int SetEnv(const char* name, const char* value, int overwrite)
{
#if defined(IUTEST_NO_SETENV) || defined(__STRICT_ANSI__) \
    || defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE)
    IUTEST_UNUSED_VAR(name);
    IUTEST_UNUSED_VAR(value);
    IUTEST_UNUSED_VAR(overwrite);
    return -1;
#elif defined(IUTEST_OS_WINDOWS)
    if( overwrite == 0 )
    {
        if( GetEnv(name) != NULL )
        {
            return 0;
        }
    }
    ::std::string expr = name;
    expr += "=";
    expr += value;
    return PutEnv(expr.c_str());
#else
    return setenv(name, value, overwrite);
#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()
{
    char buf[260] = { 0 };
    return GetCWD(buf, sizeof(buf));
}

IUTEST_IPP_INLINE int SleepMillisecFor(unsigned int millisec)
{
    volatile int x=0;
    for( unsigned int i=0; i < millisec; ++i )
    {
        x += 1;
    }
    return x;
}

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
    (void)SleepMillisecFor(millisec);
#endif

#else
    (void)SleepMillisecFor(millisec);
#endif
}

#if defined(IUTEST_OS_WINDOWS_MOBILE)
void Abort()
{
    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() 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 const char* FindLastPathSeparator(const char* path, size_t length) IUTEST_CXX_NOEXCEPT_SPEC
{
    const char* ps = path;
    const char* pe = ps + length - 1;
    while( pe >= ps )
    {
        if( IsPathSeparator(*pe) )
        {
            if( (*(pe - 1) & 0x80) == 0 )
            {
                return pe;
            }
            --pe;
        }
        --pe;
    }
    return NULL;
}

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
    return internal::posix::SetEnv(name, value, 1) == 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;
    }
    const int n = iu_snprintf(buf, size, "%s", env);
    if( n < 0 || static_cast<size_t>(n) >= size )
    {
        return false;
    }
    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)
{
    CountUp(level);
    const char* const tag =
        (level == LOG_INFO   ) ? "[  INFO ] ":
        (level == LOG_WARNING) ? "[WARNING] ":
        (level == LOG_ERROR  ) ? "[ ERROR ] ":
                                 "[ FATAL ] ";
    GetStream() << "\r\n" << tag << FormatFileLocation(file, line).c_str() << ": ";
}

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

IUTEST_IPP_INLINE void IUTestLog::CountUp(int level)
{
    if( level < LOG_LEVEL_NUM && level >= 0 )
    {
        ++GetCountTable().count[level];
    }
}

}   // 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-2016, 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
{

#if IUTEST_HAS_INLINE_VARIABLE

namespace kStrings
{
    static inline const char* const DefaultXmlReportFileName = "test_detail.xml";
    static inline const char* const UnknownFile = "unknown file";
    static inline const char* const Null = "(null)";
}

#else

namespace helper
{

#if !IUTEST_HAS_LIB
namespace {
#endif

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

#if !IUTEST_HAS_LIB
}   // namespace
#endif
}   // end of namespace helper


typedef helper::kStringsT<void> kStrings;

#endif

/**
 * @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 <locale>
#  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);

#if IUTEST_HAS_CHAR16_T

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

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

#endif

#if IUTEST_HAS_CHAR32_T

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

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

#endif

/**
 * @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
*/
template<typename CharType>
::std::string ShowWideCString(const CharType* wide_c_str)
{
    if( wide_c_str == NULL )
    {
        return kStrings::Null;
    }
    return WideStringToMultiByteString(wide_c_str);
}

#if IUTEST_HAS_CXX_HDR_CODECVT

template<typename In, typename Out, typename State>
struct codecvt : public ::std::codecvt<In, Out, State> { ~codecvt() {} };

/**
 * @brief   文字コード変換
 * @param [in]  str = 入力
 * @return  文字列
*/
#if defined(_MSC_VER)
template<typename In, typename Out, typename State>
::std::basic_string<Out> CodeConvert(const In* str, ::std::locale loc = ::std::locale(""))
{
    ::std::wstring_convert< codecvt<In, Out, State>, In> conv(&::std::use_facet< codecvt<In, Out, State> >(loc));
    return conv.to_bytes(str);
}
#else
template<typename In, typename Out, typename State>
::std::basic_string<Out> CodeConvert(const In* str)
{
    ::std::wstring_convert< codecvt<In, Out, State>, In> conv;
    //::std::wstring_convert< codecvt<In, Out, State>, In> conv(&::std::use_facet< ::std::codecvt<In, Out, State> >(loc) );
    return conv.to_bytes(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-2017, 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
#if IUTEST_HAS_CXX_HDR_CUCHAR
#  include <cuchar>
#endif

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バイト以上を要求)
 * @param [in]  size        = 出力バッファサイズ
 * @return  出力バッファ
*/
IUTEST_IPP_INLINE char* CodePointToUtf8(UInt32 code_point, char* buf, size_t size)
{
    if( code_point <= kMaxCodePoint1 )
    {
        buf[1] = '\0';
        buf[0] = static_cast<char>(code_point);
    }
    else if( code_point <= kMaxCodePoint2 )
    {
        buf[2] = '\0';
        buf[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[0] = static_cast<char>(0xC0 | code_point);
    }
    else if( code_point <= kMaxCodePoint3 )
    {
        buf[3] = '\0';
        buf[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[0] = static_cast<char>(0xE0 | code_point);
    }
    else if( code_point <= kMaxCodePoint4 )
    {
        buf[4] = '\0';
        buf[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));
        buf[0] = static_cast<char>(0xF0 | code_point);
    }
    else
    {
        iu_snprintf(buf, size, "(Invalid UTF16 0x%X)", code_point);
    }
    return buf;
}

#if defined(_MSC_VER)
IUTEST_IPP_INLINE ::std::string IUTEST_ATTRIBUTE_UNUSED_ UTF8ToSJIS(const ::std::string& str)
{
    const size_t src_length = str.length() + 1;
    const int lengthWideChar = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), src_length, NULL, 0);
    if( lengthWideChar <= 0 )
    {
        return "(convert error)";
    }

    wchar_t* wbuf = new wchar_t[lengthWideChar];
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), src_length, wbuf, lengthWideChar);

    const int lengthSJIS = WideCharToMultiByte(CP_THREAD_ACP, 0, wbuf, -1, NULL, 0, NULL, NULL);
    if( lengthSJIS <= 0 )
    {
        delete[] wbuf;
        return "(convert error)";
    }

    char* buf = new char[lengthSJIS];
    WideCharToMultiByte(CP_THREAD_ACP, 0, wbuf, -1, buf, lengthSJIS, NULL, NULL);

    std::string ret(buf);
    delete[] wbuf;
    delete[] buf;
    return ret;
}
#endif

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
#else
    iu_stringstream ss;
    for(int i=0; i < num; ++i )
    {
        UInt32 code_point = 0;
        if( str[i] == L'\0' )
        {
            break;
        }
        else if( i + 1 < num && IsUtf16SurrogatePair(str[i], str[i+1]) )
        {
            code_point = CreateCodePointFromUtf16SurrogatePair(str[i], str[i+1]);
            ++i;
        }
        else
        {
            code_point = static_cast<UInt32>(str[i]);
        }
        char buf[32];
        ss << CodePointToUtf8(code_point, buf, sizeof(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
}

#if IUTEST_HAS_CHAR16_T

IUTEST_IPP_INLINE::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToUTF8(const char16_t* str, int num)
{
#if IUTEST_HAS_CXX_HDR_CUCHAR
    IUTEST_UNUSED_VAR(num);
    const size_t length = ::std::char_traits<char16_t>::length(str);
    char16_t lead = 0, trail = 0;
    char32_t cp;
    char mbs[6];
    mbstate_t state = {};
    IUTEST_CHECK_(mbsinit(&state) != 0);
    ::std::string ret;

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
    for( size_t i = 0; i < length; ++i )
    {
        lead = str[i];

        if( lead > 0xD800 && lead < 0xDC00 )
        {
            ++i;
            trail = str[i];
            cp = (lead << 10) + trail + 0x10000 - (0xD800 << 10) - 0xDC00;
        }
        else
        {
            cp = lead;
        }
        const size_t len = ::std::c32rtomb(mbs, cp, &state);
        if( len != static_cast<size_t>(-1) )
        {
            mbs[len] = '\0';
            ret += mbs;
        }
    }
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
    return ret;
#else
    return WideStringToUTF8(reinterpret_cast<const wchar_t*>(str), num);
#endif
}

IUTEST_IPP_INLINE::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToMultiByteString(const char16_t* str, int num)
{
#if defined(_MSC_VER)
    return UTF8ToSJIS(WideStringToUTF8(str, num));
#elif IUTEST_HAS_CXX_HDR_CODECVT
    IUTEST_UNUSED_VAR(num);
    return CodeConvert<char16_t, char, ::std::mbstate_t>(str);
#elif IUTEST_HAS_CXX_HDR_CUCHAR
    IUTEST_UNUSED_VAR(num);
    const size_t length = ::std::char_traits<char16_t>::length(str);
    char16_t lead = 0, trail = 0;
    char32_t cp;
    char mbs[6];
    mbstate_t state = {};
    IUTEST_CHECK_(mbsinit(&state) != 0);
    ::std::string ret;

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
    for( size_t i = 0; i < length; ++i )
    {
        lead = str[i];

        if( lead > 0xD800 && lead < 0xDC00 )
        {
            ++i;
            trail = str[i];
            cp = (lead << 10) + trail + 0x10000 - (0xD800 << 10) - 0xDC00;
        }
        else
        {
            cp = lead;
        }
        const size_t len = ::std::c32rtomb(mbs, cp, &state);
        if( len != static_cast<size_t>(-1) )
        {
            mbs[len] = '\0';
            ret += mbs;
        }
    }
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
    return ret;
#else
    return WideStringToMultiByteString(reinterpret_cast<const wchar_t*>(str), num);
#endif
}

#endif

#if IUTEST_HAS_CHAR32_T

IUTEST_IPP_INLINE::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToUTF8(const char32_t* str, int num)
{
    IUTEST_UNUSED_VAR(num);
#if IUTEST_HAS_CXX_HDR_CUCHAR
    const size_t length = ::std::char_traits<char32_t>::length(str);
    char mbs[6];
    mbstate_t state = {};
    IUTEST_CHECK_(mbsinit(&state) != 0);
    ::std::string ret;

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
    for( size_t i = 0; i < length; ++i )
    {
        const size_t len = ::std::c32rtomb(mbs, str[i], &state);
        if( len != static_cast<size_t>(-1) )
        {
            mbs[len] = '\0';
            ret += mbs;
        }
    }
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
    return ret;
#else
    IUTEST_UNUSED_VAR(str);
    return "(convert error)";
#endif
}

IUTEST_IPP_INLINE::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToMultiByteString(const char32_t* str, int num)
{
#if defined(_MSC_VER)
    return UTF8ToSJIS(WideStringToUTF8(str, num));
#elif IUTEST_HAS_CXX_HDR_CODECVT
    IUTEST_UNUSED_VAR(num);
    return CodeConvert<char32_t, char, ::std::mbstate_t>(str);
#else
    return WideStringToUTF8(str, num);
#endif
}

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

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-2016, 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       time utility
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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

//======================================================================
// define
//! @deprecated
#if !defined(IUTEST_GetMillisec) && !IUTEST_HAS_CXX_HDR_CHRONO && !IUTEST_HAS_GETTIMEOFDAY && !defined(IUTEST_OS_WINDOWS) && !IUTEST_HAS_CLOCK
#  define IUTEST_NO_GETTIMEINMILLIS
#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();

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

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

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

public:
    // 現在の時間をミリ秒単位で取得
    static TimeInMillisec get_millisec()
    {
#if defined(IUTEST_NOT_SUPPORT_STOPWATCH)
        return 0;
#else
        return GetTimeInMillis();
#endif
    }
public:
    void start()
    {
        m_begin = get_millisec();
    }
    TimeInMillisec stop() 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-2016, 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); // NOLINT
    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); // NOLINT
    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()
{
#if IUTEST_HAS_CTIME
    return time(NULL);
#else
    return 0;
#endif
}

IUTEST_IPP_INLINE TimeInMillisec GetTimeInMillis()
{
#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
    return GetTime()*1000;
#endif
}

IUTEST_IPP_INLINE unsigned int GetIndefiniteValue()
{
    // なるべく同じにならないようにする
    static unsigned int s = static_cast<unsigned int>(GetTimeInMillis());
    s = s*1664525 + 1013904223;
    return s;
}

}   // 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 ()()
        {
            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)() { return 0; }
        static IUTEST_CXX_CONSTEXPR result_type (max)() { return static_cast<result_type>(-1); }

    private:
        result_type gen()
        {
            const unsigned int t = (m_v1 ^ (m_v1 << 11));
            m_v1 = m_v2;
            m_v2 = m_v3;
            m_v3 = m_v4;
            m_v4 = (m_v4 ^ (m_v4 >> 19)) ^ (t ^ (t >> 8));
            return m_v4;
        }
    private:
        unsigned int m_v1, m_v2, m_v3, m_v4;
    };
#endif

    Engine m_engine;

public:
    typedef unsigned int result_type;

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

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

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

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

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

    /**
     * @brief   乱数の生成
     * @details [0,1] の乱数を生成
     * @return  乱数
    */
    float genrandf()
    {
#if IUTEST_HAS_CXX_HDR_RANDOM
        return ::std::uniform_real_distribution<float>(0.0f, 1.0f)(m_engine);
#else
        return static_cast<float>(genrand())*(1.0f/4294967295.0f);
#endif
    }

    /**
     * @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 ()()
    {
        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)

#define IIUT_WORKAROUND_GENRAND(type)   \
    template<> inline type  iuRandom::genrand<type>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(type))

IIUT_WORKAROUND_GENRAND(Int64)  { return (static_cast<Int64>(genrand()) << 32) | genrand(); }
IIUT_WORKAROUND_GENRAND(UInt64) { return (static_cast<UInt64>(genrand()) << 32) | genrand(); }
IIUT_WORKAROUND_GENRAND(float)  { return genrandf(); }
IIUT_WORKAROUND_GENRAND(double) { return static_cast<double>(genrandf()); }

#undef IIUT_WORKAROUND_GENRAND

#endif

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

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

    result_type genrand()
    {
#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-2016, 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_list(const char* begin, const char* end, const char* src);
public:
    static bool match(const char* regex, const char* src);
};

#if IUTEST_HAS_CXX_HDR_REGEX

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

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_regex.ipp
 * @brief       regex
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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_list(const char* begin, const char* end, const char* src)
{
    const char* tp = begin;
    const char* end2 = tp;
    while( end2 != end )
    {
        ++end2;
        while( *end2 != ':' && end2 != end )
        {
            ++end2;
        }
        if( match_impl(tp, end2, src) )
        {
            return true;
        }

        tp = end2;
        if( *tp == ':' )
        {
            ++tp;
        }
    }
    return false;
}

IUTEST_IPP_INLINE bool iuFilterRegex::match(const char* regex, const char* src)
{
    const char* tp = regex;
    const char* end = tp;
    while( *end != '\0' && *end != '-' )
    {
        ++end;
    }

    if( *end == '-' )
    {
        if( tp != end && !match_impl_list(tp, end, src) )
        {
            return false;
        }
        tp = end + 1;
        while( *end != '\0' )
        {
            ++end;
        }
        if( match_impl_list(tp, end, src) )
        {
            return false;
        }
        return true;
    }
    return match_impl_list(tp, end, src);
}

#if IUTEST_HAS_CXX_HDR_REGEX

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

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

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-2016, 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;
template<typename T, typename ::std::string(*GetXmlPath)()>
class StderrXmlGeneratorListenerBase;

}   // 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 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() {}
    virtual ~TestEventListener() {}
public:
    virtual void OnTestProgramStart(const UnitTest& test)           = 0;    //!< テストプログラム開始時に呼ばれます
    virtual void OnTestIterationStart(const UnitTest& test
                                    , int iteration)                = 0;    //!< 単体テスト開始時に毎回呼ばれます
    virtual void OnEnvironmentsSetUpStart(const UnitTest& test)     = 0;    //!< グローバル環境設定 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() : 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() const IUTEST_CXX_NOEXCEPT_SPEC { return m_default_result_printer; }
    /**
     * @brief   デフォルトxml出力リスナー取得
    */
    TestEventListener* default_xml_generator()  const IUTEST_CXX_NOEXCEPT_SPEC { return m_default_xml_generator; }

private:
    TestEventListener* repeater() { return &m_repeater; }

    void OnTestProgramStart(const UnitTest& test)                   { m_repeater.OnTestProgramStart(test); }
    void OnTestIterationStart(const UnitTest& test, int iteration)  { m_repeater.OnTestIterationStart(test, iteration); }
    void OnEnvironmentsSetUpStart(const UnitTest& test)             { m_repeater.OnEnvironmentsSetUpStart(test); }
    void OnEnvironmentsSetUpEnd(const UnitTest& test)               { m_repeater.OnEnvironmentsSetUpEnd(test); }

    void OnTestCaseStart(const TestCase& test_case)                 { m_repeater.OnTestCaseStart(test_case); }
    void OnTestStart(const TestInfo& test_info)                     { m_repeater.OnTestStart(test_info); }
    void OnTestPartResult(const TestPartResult& test_part_result)   { m_repeater.OnTestPartResult(test_part_result); }
    void OnTestRecordProperty(const TestProperty& test_property)    { m_repeater.OnTestRecordProperty(test_property); }
    void OnTestEnd(const TestInfo& test_info)                       { m_repeater.OnTestEnd(test_info); }
    void OnTestCaseEnd(const TestCase& test_case)                   { m_repeater.OnTestCaseEnd(test_case); }

    void OnEnvironmentsTearDownStart(const UnitTest& test)          { m_repeater.OnEnvironmentsTearDownStart(test); }
    void OnEnvironmentsTearDownEnd(const UnitTest& test)            { m_repeater.OnEnvironmentsTearDownEnd(test); }
    void OnTestIterationEnd(const UnitTest& test, int iteration)    { m_repeater.OnTestIterationEnd(test, iteration); }
    void OnTestProgramEnd(const UnitTest& test)                     { m_repeater.OnTestProgramEnd(test); }

private:
    void set_default_result_printer(TestEventListener* listener);
    void set_default_xml_generator(TestEventListener* listener);

private:
    friend class UnitTestSource;
    friend class UnitTestImpl;
    friend class UnitTest;
    friend class TestInfo;
    friend class TestCase;
    friend class Test;

    friend class detail::DefaultGlobalTestPartResultReporter;
    friend class DefaultXmlGeneratorListener;
    friend class JunitXmlGeneratorListener;
    friend class DefaultResultPrintListener;
    template<typename T, typename ::std::string(*GetXmlPath)()>
    friend class detail::StderrXmlGeneratorListenerBase;

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

}   // end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_listener.ipp
 * @brief       iris unit test イベントリスナー 定義 ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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
 *          warning_into_error (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() { Release(); }
    virtual void SetUp() {}     //!< 事前処理
    virtual void TearDown() {}  //!< 事後処理
private:
    void Release();
private:
    struct should_be_SetUp {};
    virtual should_be_SetUp* Setup() 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()
        {
            m_test_flags = TestFlag::GetInstance().m_test_flags;
        }
        ~ScopedGuard()
        {
            TestFlag::GetInstance().m_test_flags = m_test_flags;
        }
    };
public:
    /**
     * @brief   フラグ
    */
    enum Kind
    {
        SHUFFLE_TESTS           = 0x00000001,   //!< シャッフルテスト
        RUN_DISABLED_TESTS      = 0x00000002,   //!< DISABLED テストも実行
        FILTERING_TESTS         = 0x00000004,   //!< テストのフィルタリング

        BREAK_ON_FAILURE        = 0x00000010,   //!< テスト失敗時にブレーク
        THROW_ON_FAILURE        = 0x00000040,   //!< 致命的な失敗時に throw する
        WARNING_INTO_ERROR      = 0x00000080,   //!< 警告をエラーとする

        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_HELP               = 0x01000000,   //!< ヘルプ表示
        SHOW_VERSION            = 0x02000000,   //!< バージョン表示
        SHOW_FEATURE            = 0x04000000,   //!< 機能の出力
        SHOW_SPEC               = 0x08000000,   //!< Specの出力

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

        SHOW_INFO_MASK          = 0x0F000000,   //!< 情報表示系マスク
        SHOW_MASK               = 0x7F000000,   //!< 表示系マスク
        MASK                    = 0x7FFFFFFF,   //!< マスク

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

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

public:
    
    static TestFlag& GetInstance() { 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() IUTEST_CXX_NOEXCEPT_SPEC {}
        Fragment(bool enabled) { SetFlag(KIND, enabled ? -1 : ~KIND); } // NOLINT
        _Myt& operator = (bool enabled) { SetFlag(KIND, enabled ? -1 : ~KIND); return *this; }
        operator bool() 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::WARNING_INTO_ERROR>    warning_into_error;
    typedef TestFlag::Fragment<TestFlag::PRINT_TIME>            print_time;
    typedef TestFlag::Fragment<TestFlag::SHOW_TESTS_LIST>       list_tests;
    typedef TestFlag::Fragment<TestFlag::SHOW_TESTS_LIST_WITH_WHERE> list_tests_with_where;

    typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION_EACH>      catch_exceptions_each;
    typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION_GLOBAL>    catch_exceptions_global;

    typedef TestFlag::Fragment<TestFlag::FILELOCATION_STYLE_MSVC>   file_location_style_msvc;
    typedef TestFlag::Fragment<TestFlag::VERBOSE>   verbose;

    /**
     * @}
    */

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

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

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

private:
    struct Variable
    {
        Variable()
            : m_random_seed(0)
            , m_current_random_seed(0)
            , m_before_origin_random_seed(0)
            , m_repeat_count(1)
            , m_testpartresult_reporter(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() { static Variable v; return v; }

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

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

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

private:
    /**
     * @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 = detail::NullableString(str);
    }
#endif

    /**
     * @brief   color オプション文字列を取得
    */
    static const char* get_color_option()
    {
        if( TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ANSI) )
        {
            return "ansi";
        }
        else if( TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ON) )
        {
            return "yes";
        }
        else if( TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_OFF) )
        {
            return "no";
        }
        return "auto";
    }
    /**
     * @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 = detail::NullableString(str);
    }

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

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

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

public:
    /**
     * @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

    /**
     * @private
     * @brief   default_package_name オプション設定用オブジェクト
    */
    typedef OptionString<get_default_package_name, set_default_package_name> default_package_name;

#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
    /**
     * @private
     * @brief   ostream_formatter オプション設定用オブジェクト
    */
    typedef class OStreamFormatter : public iu_stringstream
    {
        IUTEST_WORKAROUND_MSC_STLSTREAM_C4250()
    public:
        OStreamFormatter()
        {
            copyfmt(get_vars().m_ostream_formatter);
        }
        virtual ~OStreamFormatter()
        {
            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() { 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()
    {
        // すべて解放する
        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)
    {
        typedef ::std::vector< ::std::basic_string<CharType> > argv_t;
        for( typename argv_t::iterator it = argv.begin(); it != argv.end(); )
        {
            if( ParseCommandLineElem(it->c_str()) )
            {
                it = argv.erase(it);
            }
            else
            {
                ++it;
            }
        }
    }

    
    static bool LoadFlagFile();

private:
    template<typename CharType>
    static bool ParseCommandLineElem(CharType* argv)
    {
        typedef typename detail::mbs_ptr<CharType> formatter;

        formatter argv_format;
        const char* str = argv_format.ptr(argv);
        return ParseCommandLineElemA(str);
    }
    static bool ParseCommandLineElemA(const char* str);
    static bool ParseIutestOptionCommandLineElemA(const char* str);
    static bool SetFlag(int enable, int mask = -1);

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

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

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

/**
 * @brief   ostream_formatter オプションが適用されてた stringstream
*/
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
    }
    explicit iu_global_format_stringstream(const char* str)
        : iu_stringstream(str)
    {
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
        TestEnv::global_ostream_copyfmt(*this);
#endif
    }
    explicit 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-2017, 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-2016, 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       io stream
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2016, 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() {}
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() {}
public:
    //! 読み込み
    virtual bool Read(void* buf, size_t size, size_t cnt) = 0;

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

public:
    //! 全読み込み
    virtual ::std::string ReadAll()
    {
        ::std::string str;
        const size_t size = GetSize();
        if( size != 0 )
        {
            char* buf = new char[size+1];
            buf[size] = '\0';
            if( Read(buf, size, 1) )
            {
                str = buf;
            }
            delete [] buf;
        }
        return str;
    }
};

/**
 * @brief   ファイルIO出力ストリームインターフェイス
*/
class FileOutStream : public IOutStream
{
protected:
    FILE* m_fp;
public:
    explicit 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() {}
public:
    //! 開く
    virtual bool Open(const char* filename, int mode) = 0;
    //! 閉じる
    virtual void Close() = 0;
};

namespace detail
{

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

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

public:
    virtual void Initialize() {}

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

public:
    static IFile* New()
    {
        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() = 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() 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
{
protected:
    FILE* m_fp;
public:
    StdioFile() IUTEST_CXX_NOEXCEPT_SPEC : m_fp(NULL) {}
    virtual ~StdioFile() { 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() 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() 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;
    }
};

class StdErrorFile : public StdioFile
{
public:
    StdErrorFile() IUTEST_CXX_NOEXCEPT_SPEC {}
    virtual ~StdErrorFile() { Close(); }
public:
    /**
     * @brief   開く
     * @param [in]  filename    = ファイルパス
     * @param [in]  mode        = モード
     * @return  成否
    */
    virtual bool Open(const char* , int ) IUTEST_CXX_OVERRIDE
    {
        m_fp = stderr;
        return true;
    }
    /**
     * @brief   閉じる
    */
    virtual void Close() IUTEST_CXX_OVERRIDE
    {
        m_fp = NULL;
    }
};

#endif

#if IUTEST_HAS_STRINGSTREAM

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

    /**
     * @brief   閉じる
    */
    virtual void Close() 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() 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() IUTEST_CXX_OVERRIDE
    {
        return ss.str();
    }
protected:
    ::std::stringstream ss;
};

#endif

namespace detail
{

/**
 * @brief   何もしない IFile インターフェースクラス
*/
class NoEffectFile : public IFile
{
public:
    virtual bool Open(const char*, int) IUTEST_CXX_OVERRIDE { return true; }
    virtual void Close() IUTEST_CXX_OVERRIDE {}
    virtual bool Write(const void*, size_t, size_t) IUTEST_CXX_OVERRIDE { return true;  }
    virtual bool Read(void*, size_t, size_t) IUTEST_CXX_OVERRIDE { return true; }
    virtual size_t GetSize() IUTEST_CXX_OVERRIDE { return 0; }
};

}   // end of namespace detail
}   // 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()
{
    const ::std::string& option = get_vars().m_output_option;
    const char spec[] = "xml";
    const size_t length = sizeof(spec) - 1;
    if( option.compare(0, length, spec) == 0 )
    {
        if( (option.length() > length + 1) && (option.at(length) == ':') )
        {
            return option.substr(length + 1);
        }
        return detail::kStrings::DefaultXmlReportFileName;
    }
    return "";
}

IUTEST_IPP_INLINE::std::string TestEnv::get_report_junit_xml_filepath()
{
    const ::std::string& option = get_vars().m_output_option;
    const char spec[] = "junit";
    const size_t length = sizeof(spec) - 1;
    if( option.compare(0, length, spec) == 0 )
    {
        if( (option.length() > length + 1) && (option.at(length) == ':') )
        {
            return option.substr(length + 1);
        }
        return detail::kStrings::DefaultXmlReportFileName;
    }
    return "";
}

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)
{
    if( *str == '-' )
    {
        ++str;
        if( *str == '-' )
        {
            ++str;
            bool iuoption = false;
            {
                const char* const base_str = str;
                if( *str == 'g' )
                {
                    ++str;
                    iuoption = true;
                }
                if(*str == 'i' && *(str+1) == 'u' )
                {
                    str += 2;
                    iuoption = true;
                }
                const char option_prefix[] = "test_";
                for( int i=0, size=sizeof(option_prefix)/sizeof(option_prefix[0])-1; i < size; ++i, ++str )
                {
                    if( *str != option_prefix[i] )
                    {
                        iuoption = false;
                        str = base_str;
                        break;
                    }
                }
            }
            if( iuoption )
            {
                if( ParseIutestOptionCommandLineElemA(str) )
                {
                    return true;
                }
                // 該当するオプションがない場合はヘルプ表示
                TestFlag::SetFlag(TestFlag::SHOW_HELP);
            }
            else
            {
                if( detail::IsStringEqual(str, "help") )
                {
                    return SetFlag(TestFlag::SHOW_HELP);
                }
                if( detail::IsStringEqual(str, "version") )
                {
                    return SetFlag(TestFlag::SHOW_VERSION);
                }
                if( detail::IsStringEqual(str, "feature") )
                {
                    return SetFlag(TestFlag::SHOW_FEATURE);
                }
                if( detail::IsStringEqual(str, "spec") )
                {
                    return SetFlag(TestFlag::SHOW_SPEC);
                }
                if( detail::IsStringEqual(str, "verbose") )
                {
                    return SetFlag(TestFlag::VERBOSE);
                }
            }
        }
        else
        {
            if( detail::IsStringEqual(str, "v") )
            {
                return SetFlag(TestFlag::SHOW_VERSION);
            }
            if( detail::IsStringEqual(str, "h")
             || detail::IsStringEqual(str, "?") )
            {
                return SetFlag(TestFlag::SHOW_HELP);
            }
        }
    }
    return false;
}

IUTEST_IPP_INLINE bool TestEnv::ParseIutestOptionCommandLineElemA(const char* str)
{
    // --iutest_*
    if( detail::IsStringForwardMatching(str, "output") )
    {
        return ParseOutputOption(ParseOptionSettingStr(str));
    }
    if( detail::IsStringEqual(str, "list_tests") )
    {
        return SetFlag(TestFlag::SHOW_TESTS_LIST);
    }
    if( detail::IsStringEqual(str, "list_tests_with_where") )
    {
        return SetFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE);
    }
    if( detail::IsStringForwardMatching(str, "color") )
    {
        return ParseColorOption(ParseOptionSettingStr(str));
    }
    if( detail::IsStringEqual(str, "shuffle") )
    {
        return SetFlag(TestFlag::SHUFFLE_TESTS);
    }
    if( detail::IsStringForwardMatching(str, "random_seed") )
    {
        const char* opt = ParseOptionSettingStr(str);
        if( opt != NULL )
        {
            char* end = NULL;
            const long seed = strtol(opt, &end, 0);
            init_random(static_cast<unsigned int>(seed));
            return true;
        }
    }
    if( detail::IsStringEqual(str, "also_run_disabled_tests") )
    {
        return SetFlag(TestFlag::RUN_DISABLED_TESTS);
    }
    if( detail::IsStringForwardMatching(str, "break_on_failure") )
    {
        return ParseYesNoFlagCommandLine(str, TestFlag::BREAK_ON_FAILURE, 1);
    }
    if( detail::IsStringForwardMatching(str, "catch_exceptions") )
    {
        return ParseYesNoFlagCommandLine(str, TestFlag::CATCH_EXCEPTION, -1);
    }
    if( detail::IsStringForwardMatching(str, "throw_on_failure") )
    {
        return ParseYesNoFlagCommandLine(str, TestFlag::THROW_ON_FAILURE, 1);
    }
    if (detail::IsStringForwardMatching(str, "warning_into_error"))
    {
        return ParseYesNoFlagCommandLine(str, TestFlag::WARNING_INTO_ERROR, 1);
    }
    if( detail::IsStringForwardMatching(str, "print_time") )
    {
        return ParseYesNoFlagCommandLine(str, TestFlag::PRINT_TIME, -1);
    }
    if( detail::IsStringForwardMatching(str, "repeat") )
    {
        const char* opt = ParseOptionSettingStr(str);
        if( opt != NULL )
        {
            char* end = NULL;
            const long count = strtol(opt, &end, 0);
            set_repeat_count(static_cast<int>(count));
            return true;
        }
    }
    if( detail::IsStringForwardMatching(str, "filter") )
    {
        return ParseFilterOption(ParseOptionSettingStr(str));
    }
    if( detail::IsStringForwardMatching(str, "flagfile") )
    {
        return ParseFlagFileOption(ParseOptionSettingStr(str));
    }
#if IUTEST_HAS_STREAM_RESULT
    if( detail::IsStringForwardMatching(str, "stream_result_to") )
    {
        const char* opt = ParseOptionSettingStr(str);
        if( opt != NULL )
        {
            set_stream_result_to(opt);
            return true;
        }
    }
#endif
    if( detail::IsStringForwardMatching(str, "file_location") )
    {
        return ParseFileLocationOption(ParseOptionSettingStr(str));
    }
    if( detail::IsStringForwardMatching(str, "default_package_name") )
    {
        set_default_package_name(ParseOptionSettingStr(str));
        return true;
    }
    return false;
}

IUTEST_IPP_INLINE bool TestEnv::SetFlag(int enable, int mask)
{
    TestFlag::SetFlag(enable, mask);
    return true;
}

IUTEST_IPP_INLINE void TestEnv::LoadEnvironmentVariable()
{
    {
        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_WARNING_INTO_ERROR", var))
        {
            TestFlag::SetFlag(TestFlag::WARNING_INTO_ERROR
                , var ? TestFlag::MASK : ~(TestFlag::WARNING_INTO_ERROR));
        }
        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);
        }
        else if( detail::GetEnvironmentVariable("XML_OUTPUT_FILE", str+4, sizeof(str) - 4) )
        {
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
            memcpy(str, "xml:", 4);
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
            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()
{
    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() {}
    explicit iuStreamMessage(const char* message) : m_stream(message) {}
    iuStreamMessage(const iuStreamMessage& rhs) : m_stream(rhs.GetString()) {}

public:
    ::std::string GetString() const { return m_stream.str(); }
public:
    template<typename T>
    iuStreamMessage& operator << (const T& value)
    {
        m_stream << 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() const { return m_message.c_str(); }       //!< メッセージの取得
    const char*     file_name() const IUTEST_CXX_NOEXCEPT_SPEC { return m_file; }   //!< ファイル名の取得
    int             line_number() 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() const;
    ::std::string make_newline_message() 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-2016, 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() 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;

}   // end of namespace detail

//======================================================================
// class
/**
 * @brief   テスト結果の通知処理インターフェイス
*/
class TestPartResultReporterInterface
{
public:
    virtual ~TestPartResultReporterInterface() {}
    /**
     * @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
    {
        if( iutest::IUTEST_FLAG(warning_into_error) )
        {
            if( type == kWarning )
            {
                return true;
            }
        }
        return type > kSuccess;
    }

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

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

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

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

    /**
     * @brief   結果のタイプ取得
    */
    Type        type() 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()   const { return m_key.c_str(); }     //!< キーの取得
    const char* value() 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() : m_elapsedmsec(0) {}

public:
    /**
     * @brief   成功したかどうか
     * @return  真偽値
    */
    bool        Passed() const { return !Failed(); }
    /**
     * @brief   失敗したかどうか
     * @return  真偽値
    */
    bool        Failed() const
    {
        for( TestPartResults::const_iterator it=m_test_part_results.begin()
            , end=m_test_part_results.end(); it != end; ++it )
        {
            if( it->failed() )
            {
                return true;
            }
        }
        return false;
    }
    /**
     * @brief   スキップしたかどうか
     * @return  真偽値
    */
    bool        Skipped() const
    {
        for( TestPartResults::const_iterator it=m_test_part_results.begin()
            , end=m_test_part_results.end(); it != end; ++it )
        {
            if( it->skipped() || it->assume_failed() )
            {
                return Passed();
            }
        }
        return false;
    }

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

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

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

    /**
     * @brief   警告があるかどうか
     * @return  真偽値
    */
    bool        HasWarning() const { return HasResult(TestPartResult::kWarning); }

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

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

    /**
     * @brief   プロパティ総数の取得
     * @return  総数
    */
    int         test_property_count() 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() 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()
    {
        m_test_part_results.clear();
    }
    void Clear()
    {
        m_test_part_results.clear();
        m_test_propertys.clear();
        m_elapsedmsec = 0;
    }
    bool HasResult(TestPartResult::Type eType) const
    {
        for( TestPartResults::const_iterator it=m_test_part_results.begin()
            , end=m_test_part_results.end(); it != end; ++it )
        {
            if( it->type() == eType )
            {
                return true;
            }
        }
        return false;
    }
private:
    friend class UnitTestImpl;
    friend class TestInfo;
    friend class TestCase;
    friend class detail::DefaultGlobalTestPartResultReporter;

    TestPartResults m_test_part_results;
    TestPropertys   m_test_propertys;
    TimeInMillisec  m_elapsedmsec;

    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-2017, 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 )
    {
        const unsigned char n = buf[i];
        *os << detail::ToHex((n>>4)&0xF) << ToHex(n&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;
    }
};

}   // end of namespace formatter


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 namespace 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; // NOLINT
    *os << value;
}

}   // end of namespace 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(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

#define IIUT_DECL_TUPLE_PRINTTO(n)                                              \
    template<IUTEST_PP_ENUM_PARAMS(n, typename A)>inline void PrintTo(          \
        const tuples::tuple<IUTEST_PP_ENUM_PARAMS(n, A)>& t, iu_ostream* os) {  \
            PrintTupleTo(t, os); }

inline void PrintTo(const tuples::tuple<>& t, iu_ostream* os) { PrintTupleTo(t, os); }

IIUT_DECL_TUPLE_PRINTTO(1)
IIUT_DECL_TUPLE_PRINTTO(2)
IIUT_DECL_TUPLE_PRINTTO(3)
IIUT_DECL_TUPLE_PRINTTO(4)
IIUT_DECL_TUPLE_PRINTTO(5)
IIUT_DECL_TUPLE_PRINTTO(6)
IIUT_DECL_TUPLE_PRINTTO(7)
IIUT_DECL_TUPLE_PRINTTO(8)
IIUT_DECL_TUPLE_PRINTTO(9)

#undef IIUT_DECL_TUPLE_PRINTTO

#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(const wchar_t* str, iu_ostream* os)
{
    UniversalPrint(detail::ShowWideCString(str), os);
}
#if IUTEST_HAS_CHAR16_T
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const char16_t* str, iu_ostream* os)
{
    UniversalPrint(detail::ShowWideCString(str), os);
}
#endif
#if IUTEST_HAS_CHAR32_T && (IUTEST_HAS_CXX_HDR_CUCHAR || IUTEST_HAS_CXX_HDR_CODECVT)
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const char32_t* str, iu_ostream* os)
{
    UniversalPrint(detail::ShowWideCString(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-2017, 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() 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) {}  // NOLINT
    iu_list_iterator(const iu_list_iterator& 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 ++ () { m_node = m_node->next; return *this; }
    _Myt&       operator -- () { m_node = m_node->prev; return *this; }
    value_ptr   operator -> () IUTEST_CXX_NOEXCEPT_SPEC { return ptr(); }
    value_ref   operator *  () IUTEST_CXX_NOEXCEPT_SPEC { return *m_node; }
    value_ptr   ptr() const IUTEST_CXX_NOEXCEPT_SPEC { return m_node; }

    operator    value_ptr () { 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:
    explicit iu_list(node_ptr p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_node(p) {}

public:
    // リストの総数取得
    unsigned int count() 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() 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() IUTEST_CXX_NOEXCEPT_SPEC
    {
        return m_node;
    }
    iterator end() IUTEST_CXX_NOEXCEPT_SPEC
    {
        return iterator(NULL);
    }
    const_iterator begin() const IUTEST_CXX_NOEXCEPT_SPEC
    {
        return m_node;
    }
    const_iterator end() 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 -> () { return m_node; }
    node_ptr    operator &  () { return m_node; }   // NOLINT
    NODE&       operator *  () { 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()
    {
        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;
}

/**
 * @brief   条件に合う要素があるかどうか
*/
template<typename Node, typename Fn>
bool AnyOverList(const iu_list<Node>& list, Fn f)
{
    for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
    {
        if( ((*it).*f)() )
        {
            return true;
        }
    }
    return false;
}

}   // 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   Assertion Result
*/
class AssertionResult
{
public:
    /**
     * @brief   コンストラクタ
     * @param [in] result = テスト結果真偽値
    */
    AssertionResult(bool result) : m_result(result) {}  // NOLINT
    //! コピーコンストラクタ
    AssertionResult(const AssertionResult& rhs) : m_message(rhs.m_message), m_result(rhs.m_result) {}

    /**
     * @brief   成否
    */
    bool failed() const IUTEST_CXX_NOEXCEPT_SPEC { return !m_result; }

    /**
     * @brief   成否
    */
    bool passed() const IUTEST_CXX_NOEXCEPT_SPEC { return m_result; }

    /**
     * @brief   メッセージの取得
    */
    const char* message() const { return m_message.c_str(); }

    /**
     * @brief   メッセージの取得
     * @deprecated please use message() instead.
    */
    const char* failure_message() const { return message(); }

    
    IUTEST_CXX_EXPLICIT_CONVERSION operator bool() 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 ! () 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() { return AssertionResult(true); }
    /**
     * @brief   失敗結果の作成
    */
    static AssertionResult Failure() { 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) {}   // NOLINT
};
/**
 * @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

/**
 * @private
 * @brief   Assertion Helper
*/
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) // NOLINT
            : detail::iuCodeMessage(msg)
        {
            ScopedTrace::GetInstance().list.push_back(this);
        }
        ~ScopedMessage()
        {
            ScopedTrace::GetInstance().list.erase(this);
        }
    };
private:
    class ScopedTrace
    {
    public:
        typedef detail::iu_list<ScopedMessage> msg_list;
        msg_list list;
        static ScopedTrace& GetInstance() { 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 しないこと！テスト側の例外キャッチにかからなくなる
        const std::string append_message = fixed.GetString();
        if( !append_message.empty() )
        {
            m_part_result.add_message(" " + append_message);
        }
        ScopedTrace::GetInstance().append_message(m_part_result);

        if( TestEnv::GetGlobalTestPartResultReporter() != 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() { return AssertionResult::Success(); }
/**
 * @brief   テスト失敗を示す AssertionResult オブジェクトの取得
*/
inline AssertionResult AssertionFailure() { 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 IIUT_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 IIUT_DECL_COMPARE_HELPER_(op_name, op)                      \
    template<typename T1, typename T2>                              \
    IIUT_DECL_COMPARE_HELPER_I_(op_name, op, const T1&, const T2&)  \
    IIUT_DECL_COMPARE_HELPER_I_(op_name, op, BiggestInt, BiggestInt)

#else

#define IIUT_DECL_COMPARE_HELPER_(op_name, op)                      \
    template<typename T1, typename T2>                              \
    IIUT_DECL_COMPARE_HELPER_I_(op_name, op, const T1&, const T2&)

#endif

IIUT_DECL_COMPARE_HELPER_(NE, !=)
IIUT_DECL_COMPARE_HELPER_(LE, <=)
IIUT_DECL_COMPARE_HELPER_(LT, < )
IIUT_DECL_COMPARE_HELPER_(GE, >=)
IIUT_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_PRAGMA_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_PRAGMA_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_PRAGMA_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_PRAGMA_WARN_POP()
}

template<typename T>
inline AssertionResult CmpHelperMemCmpNE(const char* expected_str, const char* actual_str
    , const T& expected, const T& actual)
{
IUTEST_PRAGMA_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_PRAGMA_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)));
}

}   // end of namespace StrEqHelper

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

}   // end of namespace StrNeHelper

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

}   // end of namespace StrCaseEqHelper

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

}   // end of namespace StrCaseNeHelper

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-2016, 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_

//======================================================================
// 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_CURRENT_NAMESPACE_(name)               \
    class iuTest_TestCasePackage;                           \
    __if_not_exists(name::iuTest_GetTestCasePackageName) {  \
        IIUT_PACKAGE_DECL_NAME_FUNC(name)                   \
    }

#define IIUT_PACKAGE_PARENT_NAMESPACE_(name)                \
    class iuTest_TestCaseParentPackage;                     \
    __if_not_exists(name::iuTest_GetTestCaseParentPackageName) {    \
        IUTEST_PRAGMA_MSC_WARN_PUSH()                       \
        IUTEST_PRAGMA_MSC_WARN_DISABLE(4505)                \
        IIUT_PACKAGE_DECL_PARENT_NAME_FUNC(name)            \
        IUTEST_PRAGMA_MSC_WARN_POP()                        \
    }

#else

#define IIUT_PACKAGE_CURRENT_NAMESPACE_(name)               \
    class iuTest_TestCasePackage;                           \
    namespace { const int IUTEST_PP_CAT(k_iutest_package_##name##_dummy_, IUTEST_PP_UNIQUEID)   \
        IUTEST_ATTRIBUTE_UNUSED_ = ::iutest::detail::package_name_server<                       \
                iuTest_TestCasePackage>::setname(iuTest_GetTestCaseParentPackageName(           \
                    static_cast<iuTest_TestCaseParentPackage*>(NULL)) + #name ".");             \
    }

#define IIUT_PACKAGE_PARENT_NAMESPACE_(name)                \
    class iuTest_TestCaseParentPackage;                     \
    namespace { const int IUTEST_PP_CAT(k_iutest_package_##name##_parent_dummy_, IUTEST_PP_UNIQUEID)    \
        IUTEST_ATTRIBUTE_UNUSED_ = ::iutest::detail::package_name_server<iuTest_TestCaseParentPackage>  \
        ::setname(iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(NULL)));           \
    }

#endif

#define IIUT_PACKAGE_(name)                                 \
    namespace name {                                        \
        IIUT_PACKAGE_CURRENT_NAMESPACE_(name)               \
        IIUT_PACKAGE_PARENT_NAMESPACE_(name)                \
    }                                                       \
    namespace name

#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

namespace iutest {
namespace detail
{

/**
 * @private
 * @brief   パッケージ名のサーバー
*/
template<typename T>
class package_name_server
{
    static ::std::string& getname_() { static ::std::string s; return s; }
public:
    static ::std::string getname() { return getname_(); }
    static int setname(const ::std::string& s)
    {
        ::std::string& name = getname_();
        if( name.empty() )
        {
            name = s;
        }
        return 0;
    }
};

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

/**
 * @brief   パッケージ名の取得
 * @return  パッケージ名
*/
template<typename T>
::std::string iuTest_GetTestCasePackageName(T*)         // NOLINT
{
    return ::iutest::detail::package_name_server<T>::getname();
}

/**
 * @brief   親空間のパッケージ名の取得
 * @return  パッケージ名
*/
template<typename T>
::std::string iuTest_GetTestCaseParentPackageName(T*)   // NOLINT
{
    return ::iutest::detail::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_iutest_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_##_x_iutest_x_##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_(name_, var_) 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_(name_, var_) 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 IIUT_TEST_F_(macro, testfixture_, testname_)                            \
    macro(testfixture_, testname_, IIUT_TO_VARNAME_(testfixture_)               \
        , ::iutest::internal::GetTypeId< IIUT_TO_VARNAME_(testfixture_) >())

#if IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE

#define IIUT_TEST_F_A_(macro, testfixture_, testname_)                          \
    IIUT_TEST_F_( macro, IUTEST_PP_IF( IUTEST_PP_IS_BEGIN_PARENS(testfixture_)  \
        , IUTEST_ALIAS_TESTNAME_F_, IUTEST_PP_EMPTY() ) testfixture_, testname_)

#define IUTEST_TEST_F_(testfixture_, testname_)                                 \
    IIUT_TEST_F_A_(IUTEST_TEST_, testfixture_, testname_)

#define IUTEST_TEST_F_IGNORE_(testfixture_, testname_)                          \
    IIUT_TEST_F_A_( IUTEST_TEST_IGNORE_, testfixture_, testname_)

#else

#define IUTEST_TEST_F_(testfixture_, testname_)                                 \
    IIUT_TEST_F_(IUTEST_TEST_, testfixture_, testname_)

#define IUTEST_TEST_F_IGNORE_(testfixture_, testname_)                          \
    IIUT_TEST_F_( IUTEST_TEST_IGNORE_, testfixture_, testname_)

#endif

/**
 * @}
*/

/**
 * @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_)() {}                          \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE;                                 \
    };                                                                                      \
    ::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()

/**
 * @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_)() {}                          \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE { IUTEST_SKIP() << "ignored test..."; }          \
        template<typename T>void Body();                                                    \
    };                                                                                      \
    ::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()

#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_)() {}                          \
        static ::std::string MakeTestName() { return ::iutest::detail::MakeIndexTestName(       \
            IIUT_TO_NAME_STR_(testname_), ::iutest::detail::GetTypeUniqueCounter<               \
                IUTEST_TEST_CLASS_NAME_(testcase_, testname_)>()); }                            \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE { 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

/**
 * @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
 * @brief   比較検証マクロ
*/
#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

#if IUTEST_HAS_CATCH_SEH_EXCEPTION_ASSERTION

#define IIUT_SEH_THROUGH(statement)    ::iutest::detail::seh_passthrough([&](){ (void)(statement); })

#else

#define IIUT_SEH_THROUGH(statement)    (void)(statement)

#endif

/**
 * @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(IIUT_SEH_THROUGH(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(IIUT_SEH_THROUGH(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 {                                                               \
            IIUT_SEH_THROUGH(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 {                                                               \
            IIUT_SEH_THROUGH(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_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, actual, on_failure)         \
    IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTREQ    \
        , expected, actual, 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, actual, on_failure)         \
    IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTRCASEEQ    \
        , expected, actual, 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_SAME(v1, v2, on_failure)                    \
    IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSame     \
        , v1, v2, on_failure )

#define IUTEST_TEST_NULL(v, on_failure)                     \
    IUTEST_THROUGH_ANALYSIS_ASSUME_(v==IUTEST_NULLPTR       \
        , 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!=IUTEST_NULLPTR       \
        , IUTEST_PRED_FORMAT1_( ::iutest::internal::NullHelper<IUTEST_IS_NULLLITERAL(v)>::CompareNe \
            , v, 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-2017, 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-2016, 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 ~iuLogger() IUTEST_CXX_DEFAULT_FUNCTION
    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);
    static inline bool HasColorConsole();

private:
    static inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }

    static bool IsColorModeOff()
    {
#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()
    {
#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()
    {
#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);
        if( stdout_handle != INVALID_HANDLE_VALUE )
        {
            CONSOLE_SCREEN_BUFFER_INFO csbi;
            if( ::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);
                return;
            }
        }
    }
#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;
    }
    static bool has_color = HasColorConsole();
    return use_color && has_color;
}

inline bool iuConsole::HasColorConsole()
{
#if !IUTEST_HAS_COLORCONSOLE
    return false;
#else
#if defined(IUTEST_OS_WINDOWS)
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if( ::GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) )
        {
            return true;
        }
    }
#endif
    const char* env = internal::posix::GetEnv("TERM");
    const 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, "tmux")
        || IsStringEqual(env, "tmux-256color")
        || IsStringEqual(env, "rxvt-unicode")
        || IsStringEqual(env, "rxvt-unicode-256color")
        || IsStringEqual(env, "linux")
        || IsStringEqual(env, "cygwin")
        );
    return term_conf;
#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();
    /**
     * @brief   バージョン出力
    */
    static void ShowVersion();
    /**
     * @brief   機能出力
    */
    static void ShowFeature();
    /**
     * @brief   コンパイラスペック出力
    */
    static void ShowSpec();
};

inline void iuOptionMessage::ShowHelp()
{
    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_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_output=<xml|junit>[:path]\n"
        "            : Path of xml report.\n"
        "    --iutest_repeat=<count>\n"
        "            : Set the number of repetitions of the test.\n"
        "              use a negative count to repeat forever.\n"
#if IUTEST_HAS_STREAM_RESULT
        "    --iutest_stream_result_to=<host:port>\n"
        "                                     : Set stream test results server.\n"
#endif
        "    --iutest_file_location=<auto|vs|gcc>\n"
        "                                     : Format file location messages.\n"
        "    --verbose                        : Verbose option.\n"
        "    --feature                        : Show iutest feature.\n"
        "    --version, -v                    : Show iutest version.\n"
        "\n"
        "--------------------------------------------------\n"
        "License\n"
        "\n"
        "    Copyright (c) 2011-2017, 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()
{
    detail::iuConsole::output("iutest version %x.%x.%x.%x\n"
        , IUTEST_MAJORVER, IUTEST_MINORVER, IUTEST_BUILD, IUTEST_REVISION);
}


#define IIUT_SHOW_MACRO(macro)  detail::iuConsole::output("#define %s  %s\n", #macro, IUTEST_PP_TOSTRING(macro))

inline void iuOptionMessage::ShowFeature()
{
    IIUT_SHOW_MACRO(IUTEST_HAS_ANY_PARAM_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT);
    IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_RETURN);
    IIUT_SHOW_MACRO(IUTEST_HAS_AUTOFIXTURE_PARAM_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_COMBINE);
    IIUT_SHOW_MACRO(IUTEST_HAS_CONCAT);
    IIUT_SHOW_MACRO(IUTEST_HAS_CSVPARAMS);
    IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
    IIUT_SHOW_MACRO(IUTEST_HAS_GENRAND);
    IIUT_SHOW_MACRO(IUTEST_HAS_IGNORE_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_LIB);
    IIUT_SHOW_MACRO(IUTEST_HAS_MATCHERS);
    IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF);
    IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ELEMENTSARE);
    IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_REGEX);
    IIUT_SHOW_MACRO(IUTEST_HAS_MINIDUMP);
    IIUT_SHOW_MACRO(IUTEST_HAS_PACKAGE);
    IIUT_SHOW_MACRO(IUTEST_HAS_PAIRWISE);
    IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_METHOD_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR);
    IIUT_SHOW_MACRO(IUTEST_HAS_PEEP);
    IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_CLASS);
    IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_FUNC);
    IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_STATIC_FUNC);
    IIUT_SHOW_MACRO(IUTEST_HAS_PRINT_TO);
    IIUT_SHOW_MACRO(IUTEST_HAS_RANDOMVALUES);
    IIUT_SHOW_MACRO(IUTEST_HAS_REGEX);
    IIUT_SHOW_MACRO(IUTEST_HAS_REPORT_SKIPPED);
    IIUT_SHOW_MACRO(IUTEST_HAS_SOCKET);
    IIUT_SHOW_MACRO(IUTEST_HAS_SPI_LAMBDA_SUPPORT);
    IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT);
    IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT_TYPEEQ);
    IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_BUFFER);
    IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_RESULT);
    IIUT_SHOW_MACRO(IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE);
    IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS);
    IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS_JP);
    IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST);
    IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME);
    IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_P);
    IIUT_SHOW_MACRO(IUTEST_HAS_VALUESGEN);
    IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_COMBINE);
    IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_PAIRWISE);
    IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_VALUES);
    IIUT_SHOW_MACRO(IUTEST_CHECK_STRICT);
    IIUT_SHOW_MACRO(IUTEST_PLATFORM);
    IIUT_SHOW_MACRO(IUTEST_USE_THROW_ON_ASSERTION_FAILURE);
}

inline void iuOptionMessage::ShowSpec()
{
    IIUT_SHOW_MACRO(IUTEST_HAS_ANALYSIS_ASSUME);
    IIUT_SHOW_MACRO(IUTEST_HAS_ATTRIBUTE);
    IIUT_SHOW_MACRO(IUTEST_HAS_AUTO);
    IIUT_SHOW_MACRO(IUTEST_HAS_CATCH_SEH_EXCEPTION_ASSERTION);
    IIUT_SHOW_MACRO(IUTEST_HAS_CHAR16_T);
    IIUT_SHOW_MACRO(IUTEST_HAS_CHAR32_T);
    IIUT_SHOW_MACRO(IUTEST_HAS_CLOCK);
    IIUT_SHOW_MACRO(IUTEST_HAS_CONSTEXPR);
    IIUT_SHOW_MACRO(IUTEST_HAS_CONSTEXPR_IF);
    IIUT_SHOW_MACRO(IUTEST_HAS_COUNTER_MACRO);
    IIUT_SHOW_MACRO(IUTEST_HAS_CTIME);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_ARRAY);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CHRONO);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CODECVT);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CSTDINT);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CUCHAR);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_RANDOM);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_REGEX);
    IIUT_SHOW_MACRO(IUTEST_HAS_CXX11);
    IIUT_SHOW_MACRO(IUTEST_HAS_DECLTYPE);
    IIUT_SHOW_MACRO(IUTEST_HAS_DELETED_FUNCTIONS);
    IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
    IIUT_SHOW_MACRO(IUTEST_HAS_EXPLICIT_CONVERSION);
    IIUT_SHOW_MACRO(IUTEST_HAS_EXTERN_TEMPLATE);
    IIUT_SHOW_MACRO(IUTEST_HAS_GETTIMEOFDAY);
    IIUT_SHOW_MACRO(IUTEST_HAS_HDR_CXXABI);
    IIUT_SHOW_MACRO(IUTEST_HAS_HDR_SYSTIME);
    IIUT_SHOW_MACRO(IUTEST_HAS_IF_EXISTS);
    IIUT_SHOW_MACRO(IUTEST_HAS_INITIALIZER_LIST);
    IIUT_SHOW_MACRO(IUTEST_HAS_INLINE_VARIABLE);
    IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA);
    IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA_STATEMENTS);
    IIUT_SHOW_MACRO(IUTEST_HAS_NOEXCEPT);
    IIUT_SHOW_MACRO(IUTEST_HAS_NULLPTR);
    IIUT_SHOW_MACRO(IUTEST_HAS_OVERRIDE_AND_FINAL);
    IIUT_SHOW_MACRO(IUTEST_HAS_RTTI);
    IIUT_SHOW_MACRO(IUTEST_HAS_RVALUE_REFS);
    IIUT_SHOW_MACRO(IUTEST_HAS_SEH);
    IIUT_SHOW_MACRO(IUTEST_HAS_STD_BEGIN_END);
    IIUT_SHOW_MACRO(IUTEST_HAS_STD_DECLVAL);
    IIUT_SHOW_MACRO(IUTEST_HAS_STD_EMPLACE);
    IIUT_SHOW_MACRO(IUTEST_HAS_STD_QUICK_EXIT);
    IIUT_SHOW_MACRO(IUTEST_HAS_STD_STR_TO_VALUE);
    IIUT_SHOW_MACRO(IUTEST_HAS_STRINGSTREAM);
    IIUT_SHOW_MACRO(IUTEST_HAS_STRONG_ENUMS);
    IIUT_SHOW_MACRO(IUTEST_HAS_STRSTREAM);
    IIUT_SHOW_MACRO(IUTEST_HAS_TUPLE);
    IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATES);
    IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES);

#ifdef IUTEST_LIBSTDCXX_VERSION
    IIUT_SHOW_MACRO(IUTEST_LIBSTDCXX_VERSION);
#endif

#ifdef _MSC_FULL_VER
    IIUT_SHOW_MACRO(_MSC_FULL_VER);
#endif
#ifdef __GLIBCXX__
    IIUT_SHOW_MACRO(__GLIBCXX__);
#endif
#ifdef __GLIBCPP__
    IIUT_SHOW_MACRO(__GLIBCPP__);
#endif
#ifdef _LIBCPP_VERSION
    IIUT_SHOW_MACRO(_LIBCPP_VERSION);
#endif
#ifdef __POSIX_VISIBLE
    IIUT_SHOW_MACRO(__POSIX_VISIBLE);
#endif

#undef IIUT_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-2017, 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 info
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, 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-2016, 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-2016, 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:
    explicit iuITestInfoMediator(TestInfo* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_test_info(p) {}
public:
    virtual ~iuITestInfoMediator() IUTEST_CXX_DEFAULT_FUNCTION
    virtual bool HasFatalFailure() const = 0;
    virtual bool HasNonfatalFailure() const = 0;
    virtual bool HasFailure() const = 0;
    virtual bool IsSkipped() const = 0;
    TestInfo* ptr() const IUTEST_CXX_NOEXCEPT_SPEC { return m_test_info; }
};

/**
 * @brief   TestCase 仲介者インターフェイス
*/
class iuITestCaseMediator
{
protected:
    TestCase* m_test_case;
public:
    explicit iuITestCaseMediator(TestCase* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_test_case(p) {}
public:
    virtual ~iuITestCaseMediator() IUTEST_CXX_DEFAULT_FUNCTION
    virtual const char* test_case_name() const = 0;
    virtual const char* type_param() const = 0;
    TestCase* ptr() 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 MakeIndexName(size_t index);

}

//======================================================================
// class
/**
 * @brief   テストベース
*/
class Test
{
    IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(Test);

public:
    Test()
        : test_info_(NULL)
        , m_test_info(NULL)
#if IUTEST_HAS_GENRAND
        , m_random_seed(0)
#endif
    {
        CurrentTestObserver::s_current = this;
    }

    virtual ~Test()
    {
        CurrentTestObserver::s_current = NULL;
    }

public:
    /**
     * @brief   実行中の TestInfo の取得
    */
    static const TestInfo* GetCurrentTestInfo()
    {
        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() { return CurrentTestObserver::GetCurrentTest(); }


    /**
     * @brief   致命的なエラーが出たかどうか
     * @return  真偽値
    */
    static bool HasFatalFailure()
    {
        return GetCurrentTest()->m_test_info->HasFatalFailure();
    }

    /**
     * @brief   致命的ではないエラーが出たかどうか
     * @return  真偽値
    */
    static bool HasNonfatalFailure()
    {
        return GetCurrentTest()->m_test_info->HasNonfatalFailure();
    }

    /**
     * @brief   エラーが出たかどうか
     * @return  真偽値
    */
    static bool HasFailure()
    {
        return GetCurrentTest()->m_test_info->HasFailure();
    }

    /**
     * @brief   スキップされたかどうか
     * @return  真偽値
    */
    static bool IsSkipped()
    {
        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() { 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() { return m_random.genrandf(); }
    
    unsigned int    random_seed() const IUTEST_CXX_NOEXCEPT_SPEC { return m_random_seed; }

    
    detail::iuRandom& random_engine() { return m_random; }

#endif

protected:
    virtual void SetUp() {} //!< 実行前処理
#if IUTEST_HAS_AUTOFIXTURE_PARAM_TEST
    virtual void Body() {}  //!< テスト実装部
#else
    virtual void Body() = 0;    //!< テスト実装部
#endif
    virtual void TearDown() {}  //!< 実行後処理

public:
    static void SetUpTestCase() {}      //!< test case setup
    static void TearDownTestCase() {}   //!< 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() IUTEST_CXX_FINAL { return NULL; }

private:
    template<typename DMY>
    class Observer
    {
    public:
        static Test* s_current;
    public:
        static Test* GetCurrentTest() 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   値のパラメータ化テストのパラメータ情報
*/
template<typename ParamType>
struct TestParamInfo
{
    TestParamInfo(const ParamType& p, size_t i)
        : param(p), index(i) {}
    ParamType param;
    size_t index;
};

/**
 * @brief   パラメータテストインターフェース
 * @tparam  T = パラメータ型
*/
template<typename T>
class WithParamInterface
{
public:
    typedef T ParamType;    //!< パラメータ型
protected:
    virtual ~WithParamInterface() {}

public:
    /**
     * @brief   パラメータの取得
    */
    static const ParamType& GetParam()
    {
        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()
    {
        return tuples::get<N>(GetParam());
    }
#endif

    /**
     * @brief   テスト名の生成
    */
    static const ::std::string MakeTestParamName(const TestParamInfo<ParamType>& info)
    {
        return detail::MakeIndexName(info.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;
};

}   // end of namespace is_useful_testfixture_helper

template<typename T>
class is_useful_testfixture<void (int(T))> : public is_useful_testfixture_helper::is_override_setup<T>::type    // NOLINT
{
};

#endif

}   // end of namespace detail

}   // 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-2016, 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-2016, 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_

namespace iutest {

//======================================================================
// declare
class Test;

namespace detail
{

//======================================================================
// class
/**
 * @internal
 * @brief   テスト生成クラスインターフェース
*/
class iuFactoryBase
{
    IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(iuFactoryBase);
public:
    iuFactoryBase() IUTEST_CXX_NOEXCEPT_SPEC {}
    virtual ~iuFactoryBase() {}
public:
    virtual auto_ptr<Test> Create() = 0;
};

/**
 * @internal
 * @brief   テスト生成クラス
 * @tparam  Tester  = テストクラス
*/
template<class Tester>
class iuFactory : public iuFactoryBase
{
public:
    virtual auto_ptr<Test> Create() IUTEST_CXX_OVERRIDE
    {
        auto_ptr<Test> p( new Tester() );
        return p;
    }
};

/**
 * @internal
 * @brief   パラメータセットテスト生成クラスインターフェース
 * @tparam  ParamType   = パラメータの型
*/
template<typename ParamType>
class iuParamTestFactoryBase : public iuFactoryBase
{
public:
    iuParamTestFactoryBase() : m_param() {}
    explicit iuParamTestFactoryBase(ParamType param) : m_param(param) {}
public:
    void                SetParam(ParamType param) { m_param = param; }
    const ParamType&    GetParam()      const { return m_param; }
protected:
    ParamType m_param;
};


/**
 * @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() IUTEST_CXX_DEFAULT_FUNCTION
    explicit iuParamTestFactory(ParamType param) : _Mybase(param) {}

public:
    virtual auto_ptr<Test> Create() 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_

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()    const { return m_testcase->test_case_name(); }
    
    const   char*   name()              const { return m_testname.c_str(); }
    
    bool            should_run()        const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run; }
    
    bool            is_ran()            const IUTEST_CXX_NOEXCEPT_SPEC { return m_ran; }
    
    bool            is_disabled_test()  const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable; }
    
    bool            is_skipped()        const IUTEST_CXX_NOEXCEPT_SPEC { return m_skip || m_test_result.Skipped(); }
    
    bool            is_reportable()     const IUTEST_CXX_NOEXCEPT_SPEC { return m_matches_filter; }
    
    TimeInMillisec  elapsed_time()      const { return m_test_result.elapsed_time(); }
    
    const TestResult*   result()        const IUTEST_CXX_NOEXCEPT_SPEC { return &m_test_result; }

    
    const   char*   value_param()       const { return m_value_param.empty() ? NULL : m_value_param.c_str(); }
    
    const   char*   type_param()        const { return m_testcase->type_param(); }

    
    ::std::string testcase_name_with_default_package_name() const
    {
        return TestEnv::AddDefaultPackageName(test_case_name());
    }
public:
    /**
     * @brief   致命的なエラーが出たかどうか
     * @return  真偽値
    */
    bool    HasFatalFailure() const
    {
        return m_test_result.HasFatalFailure();
    }

    /**
     * @brief   致命的ではないエラーが出たかどうか
     * @return  真偽値
    */
    bool    HasNonfatalFailure() const
    {
        return m_test_result.HasNonfatalFailure();
    }

    /**
     * @brief   エラーが出たかどうか
     * @return  真偽値
    */
    bool    HasFailure() const
    {
        return m_test_result.Failed();
    }

    /**
     * @brief   警告があるかどうか
     * @return  真偽値
    */
    bool    HasWarning() const
    {
        return m_test_result.HasWarning();
    }

    /**
     * @brief   成功したかどうか
     * @return  真偽値
    */
    bool    Passed() const
    {
        if( is_skipped() )
        {
            return false;
        }
        return m_test_result.Passed();
    }

public:
    
    ::std::string test_full_name() const
    {
        ::std::string fullname = test_case_name();
        fullname += ".";
        fullname += name();
        return fullname;
    }

    
    ::std::string test_name_with_where() const
    {
        ::std::string str = m_testname;
        if( value_param() != 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();

private:
    void RunImpl();

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

    /*
     * @brief   テストのフィルタリング
     * @return  実行する場合は真
    */
    bool filter();

    /**
    * @brief    テストのスキップ
    */
    void skip() { m_skip = true; }

private:
    class Mediator IUTEST_CXX_FINAL : public detail::iuITestInfoMediator
    {
    public:
        explicit Mediator(TestInfo* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : iuITestInfoMediator(p) {}
    public:
        virtual bool HasFatalFailure() const IUTEST_CXX_OVERRIDE
        {
            return ptr()->HasFatalFailure();
        }
        virtual bool HasNonfatalFailure() const IUTEST_CXX_OVERRIDE
        {
            return ptr()->HasNonfatalFailure();
        }
        virtual bool HasFailure() const IUTEST_CXX_OVERRIDE
        {
            return ptr()->HasFailure();
        }
        virtual bool IsSkipped() 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-2016, 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()
{
    if( !should_run() )
    {
        return true;
    }

    // テスト開始
    TestEnv::event_listeners().OnTestStart(*this);

    RunImpl();

    // テスト終了
    TestEnv::event_listeners().OnTestEnd(*this);
    return !HasFailure();
}

IUTEST_IPP_INLINE void TestInfo::RunImpl()
{
    detail::iuStopWatch sw;
    TimeInMillisec elapsedmsec = 0;

    m_ran = true;

#if IUTEST_HAS_EXCEPTIONS
    if( TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_EACH) )
    {
        detail::auto_ptr<Test> p = m_factory->Create();
        try
        {
            sw.start();
#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 (const TestPartResult::Type& eType)
        {
            elapsedmsec = sw.stop();
            if( TestPartResult::type_is_failed(eType) && TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE) )
            {
                throw;
            }
        }
        catch (...)
        {
            elapsedmsec = sw.stop();
            iutest::AssertionHelper(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)
    char path[IUTEST_MAX_PATH];
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
    _snprintf(path, sizeof(path), "%s_%s.dump", test_case_name(), name());
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()
{
    m_ran = false;
    m_skip = false;
    m_test_result.Clear();
}

IUTEST_IPP_INLINE bool TestInfo::filter()
{
    bool run = true;
    // 無効テストなら実行しない
    if( !TestFlag::IsEnableFlag(TestFlag::RUN_DISABLED_TESTS)
        && is_disabled_test() )
    {
        run = false;
    }
    bool match = true;
    if( TestFlag::IsEnableFlag(TestFlag::FILTERING_TESTS) )
    {
        if( !detail::iuFilterRegex::match(TestEnv::test_filter(), test_full_name().c_str()) )
        {
            match = false;
            run = false;
        }
    }
    m_matches_filter = match;
    m_should_run = run;
    return m_should_run;
}

}   // 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() {}

public:
    
    const char*     name()                  const { return m_testcase_name.c_str(); }

    
    int             total_test_count()      const IUTEST_CXX_NOEXCEPT_SPEC { return m_testinfos.size(); }
    
    int             reportable_test_count() const;
    
    int             test_to_run_count()     const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num; }
    
    int             failed_test_count()     const;
    
    int             disabled_test_count()   const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable_num; }
    
    int             reportable_disabled_test_count() const;
    
    int             successful_test_count() const;
    
    int             skip_test_count()       const;
    
    int             reportable_skip_test_count() const;
    
    int             test_run_skipped_count() const;
    
    int             reportable_test_run_skipped_count() const;
    
    TimeInMillisec  elapsed_time()          const IUTEST_CXX_NOEXCEPT_SPEC { return m_elapsedmsec; }
    
    TimeInMillisec  start_timestamp()       const IUTEST_CXX_NOEXCEPT_SPEC{ return m_start_timestamp; }

    
    const TestInfo* GetTestInfo(int index)  const { return m_testinfos[index]; }
    
    bool            should_run()            const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num != 0; }

    
    bool            Passed()                const { return failed_test_count() == 0 && m_ad_hoc_testresult.Passed(); }
    
    bool            Failed()                const { return !Passed(); }

    
    virtual const char* type_param()        const { return NULL; }

    
    ::std::string testcase_name_with_where() 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() const
    {
        return TestEnv::AddDefaultPackageName(name());
    }

    
    const TestResult* ad_hoc_testresult() 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();

    /**
     * @brief   実行
     * @return  成否
    */
    bool RunImpl();

private:
    /**
     * @brief   セットアップのスキップチェック
    */
    bool CheckSetUpSkipped();

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();
    /*
     * @brief   テストのフィルタリング
     * @return  実行する場合は真
    */
    bool filter();

private:
    friend bool operator == (const TestCase& lhs, const TestCase& rhs)
    {
        return (lhs.m_id == rhs.m_id) && (strcmp(lhs.name(), rhs.name()) == 0);
    }

    void push_back(TestInfo* p) { m_testinfos.push_back(p); }

private:
    iuTestInfos::const_iterator begin() const       { return m_testinfos.begin(); }
    iuTestInfos::const_iterator end()   const       { return m_testinfos.end(); }
    TestTypeId                  get_typeid() const IUTEST_CXX_NOEXCEPT_SPEC { return m_id; }

private:
    bool HasWarning() const { return m_ad_hoc_testresult.HasWarning() || detail::AnyOverList(m_testinfos, &TestInfo::HasWarning); }

private:
    static bool IsSuccessfulTest(const TestInfo* p) { return p->is_ran() && p->Passed(); }
    static bool IsFailedTest(const TestInfo* p) { return p->should_run() && p->HasFailure(); }
    static bool IsSkipTest(const TestInfo* p) { return !p->is_ran() || p->is_skipped(); }
    static bool IsReportableSkipTest(const TestInfo* p) { return p->is_reportable() && IsSkipTest(p); }
    static bool IsRunSkippedTest(const TestInfo* p) { return p->should_run() && p->is_skipped(); }
    static bool IsReportableRunSkippedTest(const TestInfo* p) { return p->is_reportable() && IsRunSkippedTest(p); }
    static bool IsReportableDisabledTest(const TestInfo* p) { return p->is_reportable() && p->is_disabled_test(); }

private:
    friend class UnitTestImpl;
    friend class UnitTest;

#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() 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:
    explicit TestCaseMediator(TestCase* p) IUTEST_CXX_NOEXCEPT_SPEC : iuITestCaseMediator(p) {}
public:
    virtual const char* test_case_name() const IUTEST_CXX_OVERRIDE { return m_test_case->name(); }
    virtual const char* type_param()     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       testcase implimentation
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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()
{
    if( !should_run() )
    {
        return true;
    }

    if( TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS) )
    {
        detail::RandomShuffle(m_testinfos, TestEnv::genrand());
    }

    // テスト開始
    bool result=false;

    m_start_timestamp = detail::GetTimeInMillis();
    TestEnv::event_listeners().OnTestCaseStart(*this);
#if IUTEST_HAS_EXCEPTIONS
    if( TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_EACH) )
    {
        try
        {
            result = RunImpl();
        }
        catch( const TestPartResult::Type& eType )
        {
            CheckSetUpSkipped();

            if( TestPartResult::type_is_failed(eType) && TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE) )
            {
                throw;
            }
        }
        catch( ... )
        {
            throw;
        }
    }
    else
#endif
    {
        result = RunImpl();
    }
    // テスト終了
    TestEnv::event_listeners().OnTestCaseEnd(*this);

    return result;
}

IUTEST_IPP_INLINE bool TestCase::RunImpl()
{
    bool result=true;
    m_elapsedmsec = 0;

    m_setup();

    if( m_ad_hoc_testresult.HasFatalFailure() )
    {
        return false;
    }

    if( CheckSetUpSkipped() )
    {
        return true;
    }

    {
        detail::iuStopWatch sw;
        sw.start();
        for( iuTestInfos::iterator it = m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
        {
            // 実行
            if( !(it)->Run() )
            {
                result = false;
            }
        }
        m_elapsedmsec = sw.stop();
    }

    m_teardown();
    if( m_ad_hoc_testresult.HasFatalFailure() )
    {
        return false;
    }
    return result;
}

IUTEST_IPP_INLINE bool TestCase::CheckSetUpSkipped()
{
    if(m_ad_hoc_testresult.Skipped())
    {
        for(iuTestInfos::iterator it = m_testinfos.begin(), end = m_testinfos.end(); it != end; ++it)
        {
            (it)->skip();
        }
        return true;
    }
    return false;
}

IUTEST_IPP_INLINE void TestCase::clear()
{
    m_ad_hoc_testresult.Clear();
    for( iuTestInfos::iterator it = m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
    {
        (it)->clear();
    }
}

IUTEST_IPP_INLINE bool TestCase::filter()
{
    m_should_run_num = 0;
    m_disable_num = 0;
    for( iuTestInfos::iterator it = m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
    {
        if( m_disable )
        {
            // 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() const
{
    return detail::CountIfOverList(m_testinfos, &TestInfo::is_reportable);
}

IUTEST_IPP_INLINE int TestCase::failed_test_count() const
{
    if( !should_run() )
    {
        return 0;
    }
    //if( m_ad_hoc_testresult.Failed() ) return m_testinfos.count();
    return detail::CountIf(m_testinfos, IsFailedTest);
}

IUTEST_IPP_INLINE int TestCase::successful_test_count() 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() const
{
    if( !should_run() )
    {
        return total_test_count();
    }
    return detail::CountIf(m_testinfos, IsSkipTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_skip_test_count() const
{
    if( !should_run() )
    {
        return reportable_test_count();
    }
    return detail::CountIf(m_testinfos, IsReportableSkipTest);
}

IUTEST_IPP_INLINE int TestCase::test_run_skipped_count() const
{
    if( !should_run() )
    {
        return 0;
    }
    return detail::CountIf(m_testinfos, IsRunSkippedTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_test_run_skipped_count() const
{
    if( !should_run() )
    {
        return 0;
    }
    return detail::CountIf(m_testinfos, IsReportableRunSkippedTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_disabled_test_count() 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() : m_total_test_num(0), m_disable_num(0), m_should_run_num(0)
        , m_current_testcase(NULL), m_elapsedmsec(0)
    {
        ptr() = this;
    }
    ~UnitTestImpl() { TerminateImpl(); }

public:
    /**
     * @brief   テスト中のテストの TestResult の取得
    */
    static TestResult* current_test_result();

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

protected:
    /**
     * @brief   テストのリストアップ
    */
    int Listup() const;

    /**
     * @brief   テストのリストアップ(with where)
    */
    int ListupWithWhere() const;

    /**
     * @brief   事前処理
    */
    bool PreRunner();

    /**
     * @brief   テスト結果のクリア
    */
    void ClearNonAdHocTestResult();

    /**
     * @brief   ad_hoc_testresult のクリア
    */
    void ClearAdHocTestResult()
    {
        m_ad_hoc_testresult.Clear();
    }

private:
    /**
     * @brief   RecordProperty
    */
    static void RecordProperty(const TestProperty& prop);

    /**
     * @brief   FindTestCase
    */
    TestCase* FindTestCase(const char* testcase_name, TestTypeId id);

    /**
     * @brief   Do information options
    */
    bool DoInfoOptions();

private:
    /**
     * @brief   セットアップ
    */
    void InitializeImpl();
    /**
     * @brief   後片付け
    */
    void TerminateImpl();

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() 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]  index       = インデックス
*/
::std::string MakeIndexName(size_t index);

/**
 * @brief   テスト名の作成
 * @param [in]  basename    = ベース名
 * @param [in]  index       = インデックス
*/
::std::string MakeIndexTestName(const char* basename, size_t index);

/**
 * @brief   テスト名の作成
 * @param [in]  basename    = ベース名
 * @param [in]  parame_name = パラメータ名
*/
::std::string MakeParamTestName(const ::std::string& basename, const ::std::string& parame_name);

/**
 * @brief   テスト名の作成
 * @param [in]  basename    = ベース名
 * @param [in]  index       = インデックス
*/
template<typename T>
::std::string MakeIndexTypedTestName(const char* basename, size_t 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, size_t index);

/**
 * @brief   テスト名の作成
 * @param [in]  prefix      = prefix
 * @param [in]  basename    = ベース名
 * @param [in]  index       = インデックス
*/
template<typename T>
::std::string MakePrefixedIndexTypedTestName(const char* prefix, const char* basename, size_t index)
{
#if IUTEST_HAS_RTTI
    ::std::string name = prefix;
    if( !name.empty() )
    {
        name += "/";
    }
    name += MakeIndexTypedTestName<T>(basename, index);
    return name;
#else
    return MakePrefixedIndexTestName(prefix, basename, index);
#endif
}

}   // 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-2017, 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()
{
    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()
{
    const 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() 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() 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()
{
    InitializeImpl();

    if( DoInfoOptions() )
    {
        TestFlag::SetFlag(0, ~TestFlag::SHOW_MASK);
        return false;
    }
    return true;
}

IUTEST_IPP_INLINE void UnitTestImpl::ClearNonAdHocTestResult()
{
    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 bool UnitTestImpl::DoInfoOptions()
{
    if( TestFlag::IsEnableFlag(TestFlag::SHOW_INFO_MASK) )
    {
        if( TestFlag::IsEnableFlag(TestFlag::SHOW_HELP) )
        {
            detail::iuOptionMessage::ShowHelp();
        }
        if( TestFlag::IsEnableFlag(TestFlag::SHOW_VERSION) )
        {
            detail::iuOptionMessage::ShowVersion();
        }
        if( TestFlag::IsEnableFlag(TestFlag::SHOW_FEATURE) )
        {
            detail::iuOptionMessage::ShowFeature();
        }
        if( TestFlag::IsEnableFlag(TestFlag::SHOW_SPEC) )
        {
            detail::iuOptionMessage::ShowSpec();
        }
        return true;
    }
    if( TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE) )
    {
        ListupWithWhere();
        return true;
    }
    if( TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST) )
    {
        Listup();
        return true;
    }
    return false;
}

IUTEST_IPP_INLINE void UnitTestImpl::InitializeImpl()
{
#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) || defined(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()
{
    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 MakeIndexName(size_t index)
{
    iu_stringstream strm;
    strm << index;
    return strm.str();
}

IUTEST_IPP_INLINE ::std::string MakeIndexTestName(const char* basename, size_t index)
{
    ::std::string name = basename;
    name += "/";
    name += MakeIndexName(index);
    return name;
}

IUTEST_IPP_INLINE::std::string MakeParamTestName(const ::std::string& basename, const ::std::string& param_name)
{
    if( param_name.empty() )
    {
        return basename;
    }
    ::std::string name = basename;
    name += "/";
    name += param_name;
    return name;
}

IUTEST_IPP_INLINE ::std::string MakePrefixedIndexTestName(const char* prefix, const char* basename, size_t index)
{
    ::std::string name = prefix;
    if( !name.empty() )
    {
        name += "/";
    }
    name += MakeIndexTestName(basename, index);
    return name;
}

}   // 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() 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() 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()
        {
            Detach();
        }
        void Attach(TestPartResultReporterInterface* p)
        {
            m_origin = TestEnv::GetGlobalTestPartResultReporter();
            TestEnv::SetGlobalTestPartResultReporter(p);
        }
        void Detach()
        {
            TestEnv::SetGlobalTestPartResultReporter(m_origin);
        }
    public:
        void ReportTestPartResultOrigin(const TestPartResult& result)
        {
            if( m_origin )
            {
                m_origin->ReportTestPartResult(result);
            }
        }
    private:
        TestPartResultReporterInterface* m_origin;
    };

public:
    template<typename COND, typename REPORTER=DefaultGlobalTestPartResultReporter>
    class Counter : public REPORTER
    {
        typedef REPORTER _Mybase;
    public:
        Counter() : m_count(0)
        {
            m_holder.Attach(this);
        }
        virtual void ReportTestPartResult(const TestPartResult& result) IUTEST_CXX_OVERRIDE
        {
            if( m_cond(result) )
            {
                ++m_count;
            }
            _Mybase::ReportTestPartResult(result);
        }
    public:
        int count() 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()
        {
            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() const IUTEST_CXX_NOEXCEPT_SPEC { return m_results.size(); }
        const TestPartResult& GetTestPartResult(int index) const { return m_results[index]; }

        void ReportTestPartResult()
        {
            for( TestPartResults::iterator it=m_results.begin(); it != m_results.end(); ++it )
            {
                m_holder.ReportTestPartResultOrigin(*it);
            }
        }
    private:
        ReporterHolder m_holder;
        TestPartResults m_results;
    };
};

//======================================================================
// 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-2016, 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-2017, 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_

#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)();
public:
    virtual ~iuIParamGenerator() {}
public:
    virtual void    Begin() = 0;            //!< パラメータリストの先頭に移動
    virtual T       GetCurrent() const = 0; //!< 現在のパラメータを取得
    virtual void    Next() = 0;             //!< パラメータを取得して次に移動
    virtual bool    IsEnd() 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) {} // NOLINT

public:
    operator iuIParamGenerator<T>* () 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() IUTEST_CXX_OVERRIDE { m_pInterface->Begin(); }
    virtual T       GetCurrent() const IUTEST_CXX_OVERRIDE { return m_pInterface->GetCurrent(); }
    virtual void    Next() IUTEST_CXX_OVERRIDE { m_pInterface->Next(); }
    virtual bool    IsEnd() 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)
        : m_begin(begin)
        , m_end(end)
        , m_step(step)
        , m_cur(begin)
    {
    }

public:
    virtual void    Begin() IUTEST_CXX_OVERRIDE { m_cur = m_begin; }
    virtual T       GetCurrent() const IUTEST_CXX_OVERRIDE { return m_cur; }
    virtual void    Next() IUTEST_CXX_OVERRIDE { m_cur = static_cast<T>(m_cur + m_step); }
    virtual bool    IsEnd() const IUTEST_CXX_OVERRIDE { return !(m_cur < m_end); }
};

/**
 * @brief   真偽値パラメータ生成器
*/
class iuBoolParamsGenerator : public iuIParamGenerator<bool>
{
    int m_n;
    bool m_cur;
public:
    iuBoolParamsGenerator()
        : m_n(0)
        , m_cur(false)
    {}

public:
    virtual void    Begin() IUTEST_CXX_OVERRIDE { m_cur = false; m_n = 0; }
    virtual bool    GetCurrent() const IUTEST_CXX_OVERRIDE { return m_cur; }
    virtual void    Next() IUTEST_CXX_OVERRIDE { ++m_n; m_cur = !m_cur; }
    virtual bool    IsEnd() 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:
    explicit iuValuesInParamsGenerator(const params_t& values)
        : m_values(values) {}
    template<typename Container>
    explicit iuValuesInParamsGenerator(const Container& values)
    {
        m_values.insert(m_values.end(), values.begin(), values.end());
    }
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
    template<typename TT, size_t SIZE>
    explicit 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() IUTEST_CXX_OVERRIDE { m_it = m_values.begin(); }
    virtual T       GetCurrent() const IUTEST_CXX_OVERRIDE { return *m_it; }
    virtual void    Next() IUTEST_CXX_OVERRIDE { ++m_it; }
    virtual bool    IsEnd() 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>* ()
    {
        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[sizeof...(Args)];

        template<typename U>
        void operator ()(int index, const U& value) { val[index] = value; }

        explicit make_array(const _MyTuple& t)
        {
            tuples::tuple_foreach(t, *this);
        };
    };
public:
    explicit iuValueArray(const Args&... args)
        : v(args...)
    {}

#if defined(__clang__) && defined(IUTEST_LIBSTDCXX_VERSION) && IUTEST_LIBSTDCXX_VERSION >= 40900
#if IUTEST_HAS_RVALUE_REFS
    // http://stackoverflow.com/questions/23374953/why-does-this-exceed-the-maximum-recursive-template-depth
    iuValueArray(const iuValueArray& rhs)
        : v(rhs.v) {}
    iuValueArray(iuValueArray&& rhs)
        : v(rhs.v) {}
#endif
#endif

public:
    template<typename T>
    operator iuIParamGenerator<T>* () const
    {
        make_array<T> ar(v);
#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>* () 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>* () 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 kCount = sizeof...(Args);

    struct begin_func
    {
        template<typename T>
        void operator ()(int, T& value) const { value.Begin(); }
    };

    template<int index, int end, typename Tuple>
    bool is_end_foreach(Tuple& t
        , typename detail::enable_if<index != end, void>::type*& = detail::enabler::value ) const
    {
        const bool b = tuples::get<index>(t).IsEnd();
        return b && is_end_foreach<index+1, end>(t);
    }
    template<int index, int end, typename Tuple>
    bool is_end_foreach(Tuple&
        , typename detail::enable_if<index == end, void>::type*& = detail::enabler::value ) const
    {
        return true;
    }

    template<int index, int end, typename Tuple>
    void next_foreach(Tuple& t
        , typename detail::enable_if<index != end, void>::type*& = detail::enabler::value )
    {
        next_foreach<index+1, end>(t);
        if( is_end_foreach<index+1, end>(t) )
        {
            tuples::get<index>(t).Next();
            if( !tuples::get<index>(t).IsEnd() )
            {
                tuples::tuple_foreach<index + 1>(t, begin_func());
            }
        }
    }
    template<int index, int end, typename Tuple>
    void next_foreach(Tuple&
        , typename detail::enable_if<index == end, void>::type*& = detail::enabler::value )
    {
    }

    template<int index, int end, typename T1, typename ...TArgs>
    tuples::tuple<T1, TArgs...> current_foreach(
        typename detail::enable_if<index != end-1, void>::type*& = detail::enabler::value ) const
    {
        return ::std::tuple_cat( tuples::tuple<T1>(tuples::get<index>(v).GetCurrent())
            , current_foreach<index+1, end, TArgs...>());
    }
    template<int index, int end, typename T1, typename ...TArgs>
    tuples::tuple<T1> current_foreach(
        typename detail::enable_if<index == end-1, void>::type*& = detail::enabler::value ) const
    {
        return tuples::tuple<T1>(tuples::get<index>(v).GetCurrent());
    }

public:
    typedef tuples::tuple<Args...> ParamType;
public:
    iuCartesianProductGenerator() {}

public:
    virtual void Begin() IUTEST_CXX_OVERRIDE
    {
        tuples::tuple_foreach(v, begin_func());
    }
    virtual void Next() IUTEST_CXX_OVERRIDE
    {
        if( !IsEnd() )
        {
            next_foreach<0, kCount>(v);
        }
    }
    virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
    {
        return is_end_foreach<0, kCount>(v);
    }
    virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
    {
        return current_foreach<0, kCount, Args...>();
    }

    _MyTuple& generators() { return v; }
private:
    _MyTuple v;
};

template<typename... Generator>
class iuCartesianProductHolder
{
    typedef iuCartesianProductHolder<Generator...> _Myt;
    typedef tuples::tuple<const Generator...> _MyTuple;

public:
    explicit iuCartesianProductHolder(const Generator&... generators)
        : v(generators...) {}

public:
    template<typename... Args>
    operator iuIParamGenerator< tuples::tuple<Args...> >* () const
    {
        iuCartesianProductGenerator<Args...>* p = new iuCartesianProductGenerator<Args...>();
        tuples::tuple_cast_copy(p->generators(), v);
        return p;
    }

public:
#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() IUTEST_CXX_OVERRIDE
    {
        m_g1.Begin();
        m_g2.Begin();
    }
    virtual void Next() 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() 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() 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() 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() 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) > >* () 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() { 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 )
            {
                // 仮に入ったとして重複がないか調べる
                UInt32 overlap = 0;
                for( int i=0; i < N; ++i )
                {
                    if( indexes.index[i] == -1 || i == free_raw )
                    {
                        continue;
                    }
                    PairInfo tmp(i, free_raw, indexes.index[i], free_idx);
                    iterator it2 = Find(list, tmp, list.begin());
                    while(it2 != end)
                    {
                        ++overlap;
                        ++it2;
                        it2 = Find(list, tmp, it2);
                    }
                }
                if( overlap == 0 )
                {
                    return it;
                }
                if( find == list.end()
                    || (overlap < max_overlap) )
                {
                    find = it;
                    max_overlap = overlap;
                }
            }
        }
        if( find != list.end() )
        {
            return find;
        }

        typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
        for( iterator it = start, end=list.end(); it != end; ++it )
        {
            ParamIndexes<N>& indexes = *it;
            if( indexes.index[pair_info.raw1] == -1 && indexes.index[pair_info.raw2] == -1 )
            {
                return it;
            }
        }
        return list.end();
    }
};

#if IUTEST_HAS_VARIADIC_PAIRWISE

template<typename... Args>
class iuPairwiseGenerator : public iuPairwiseGeneratorBase
{
    typedef tuples::tuple< Args... > ParamType;
    typedef tuples::tuple< iuParamGenerator<Args>... > GeneratorTuple;
    static const int kRAW_COUNT = sizeof...(Args);

    typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;
    typedef ::std::vector< _MyParamIndexes > ParamIndexesList;

    typedef tuples::tuple< ::std::vector<Args>... > ParamsTuple;

public:
    static iuIParamGenerator< ParamType >* Create(GeneratorTuple& generators)
    {
        ParamIndexesList list;
        ParamVecotrs param_vectors(generators);

        MakeIndexList(list, param_vectors.count_list);

        ::std::vector<ParamType> params;
        for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
        {
            const _MyParamIndexes& indexes = *it;
            params.push_back(MakeParam<0, Args...>(param_vectors.params_list, indexes));
        }

        return new iuValuesInParamsGenerator< ParamType >(params);
    }
private:
    template<int N, typename T1, typename... TArgs>
    static tuples::tuple<T1, TArgs...> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
        , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
    {
        return ::std::tuple_cat( tuples::tuple<T1>(GetParam(tuples::get<N>(list), indexes, N))
            , MakeParam<N+1, TArgs...>(list, indexes) );
    }
    template<int N, typename T1, typename... TArgs>
    static tuples::tuple<T1> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
        , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
    {
        return tuples::tuple<T1>( GetParam( tuples::get<N>(list), indexes, N) );
    }

    struct ParamVecotrs
    {
        ParamsTuple params_list;
        int count_list[kRAW_COUNT];

        template<int N>
        void MakeParamVecotrs(GeneratorTuple& generators
            , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
        {
            MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
            count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
            MakeParamVecotrs<N+1>(generators);
        }
        template<int N>
        void MakeParamVecotrs(GeneratorTuple& generators
            , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
        {
            MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
            count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
        }

        explicit ParamVecotrs(GeneratorTuple& generators)
        {
            MakeParamVecotrs<0>(generators);
        }
    };
};

template<typename... Generator>
class iuPairwiseHolder
{
    typedef iuPairwiseHolder<Generator...> _Myt;
    typedef tuples::tuple<const Generator...> _MyTuple;

public:
    explicit iuPairwiseHolder(const Generator&... generators)
        : v(generators...) {}

public:
    template<typename... Args>
    operator iuIParamGenerator< tuples::tuple<Args...> >* () const
    {
        tuples::tuple< iuParamGenerator<Args>... > generators;
        tuples::tuple_cast_copy(generators, v);
        return iuPairwiseGenerator<Args...>::Create(generators);
    }

public:
#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() IUTEST_CXX_OVERRIDE
    {
        m_g1.Begin();
        m_g2.Begin();
    }
    virtual void Next() 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() const IUTEST_CXX_OVERRIDE
    {
        return m_g1.IsEnd() && m_g2.IsEnd();
    }
    virtual ParamType GetCurrent() 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 kRAW_COUNT = 3;
    typedef ParamIndexes<kRAW_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) > >* () 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>* () 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 ()()
    {
        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:
    explicit 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>* () 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_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_genparams_from_file.hpp
 * @brief       iris unit test parameter generator from file
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2015-2017, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_GENPARAMS_FROM_FILE_HPP_81CDA6E7_945B_4F72_873B_104264DF7132_
#define INCG_IRIS_IUTEST_GENPARAMS_FROM_FILE_HPP_81CDA6E7_945B_4F72_873B_104264DF7132_

#if IUTEST_HAS_CSVPARAMS

namespace iutest {
namespace detail
{

/**
 * @brief   csv ファイルからのパラメータ生成器
 * @tparam T    = パラメータ型
*/
template<typename T>
class iuCsvFileParamsGenerator : public iuValuesInParamsGenerator<T>
{
    typedef ::std::vector<T> params_t;
public:
    /**
     * @brief   コンストラクタ
     * @param [in]  path        = ファイルパス
     * @param [in]  delimiter   = 区切り文字
    */
    explicit iuCsvFileParamsGenerator(const ::std::string& path, char delimiter = ',')
        : iuValuesInParamsGenerator<T>(ReadParams(path, delimiter))
    {
    }

private:
    bool ToParam(const ::std::string& data, T& param)
    {
        ::std::istringstream strm(data);
        if( strm >> param )
        {
            return true;
        }
        return false;
    }

private:
    void AppendParams(params_t& params, const ::std::string& data)
    {
        if( StringIsBlank(data) )
        {
            return;
        }
        T param;
        if( !ToParam(data, param) )
        {
            return;
        }
        params.push_back(param);
    }
    params_t ReadParams(const ::std::string& path, char delimiter = ',')
    {
        params_t params;
        IFile* fp = detail::IFileSystem::New();
        if( fp != NULL )
        {
            if( fp->Open(path.c_str(), IFile::OpenRead) )
            {
                const ::std::string dataset = fp->ReadAll();
                ::std::string::size_type prev = 0;
                ::std::string::size_type pos = 0;
                while( pos = dataset.find(delimiter, prev), pos != ::std::string::npos )
                {
                    const ::std::string data = dataset.substr(prev, pos - prev);
                    AppendParams(params, data);
                    ++pos;
                    prev = pos;
                }
                AppendParams(params, dataset.substr(prev));
            }
            else
            {
                fprintf(stderr, "Unable to open file \"%s\".\n", path.c_str());
                fflush(stderr);
            }
            detail::IFileSystem::Free(fp);
        }
        IUTEST_CHECK_(!params.empty());
        return params;
    }
};

template<>inline bool iuCsvFileParamsGenerator<float>::ToParam(const ::std::string& data, float& param)
{
#if IUTEST_HAS_STD_STR_TO_VALUE
    param = std::stof(data);
    return true;
#else
    ::std::istringstream strm(data);
    if( !(strm >> param) )
    {
        param = static_cast<float>(atof(data.c_str()));
    }
    return true;
#endif
}


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

#endif

#endif // INCG_IRIS_IUTEST_GENPARAMS_FROM_FILE_HPP_81CDA6E7_945B_4F72_873B_104264DF7132_

#if IUTEST_HAS_PARAM_TEST
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_pool.hpp
 * @brief       iris unit test memory pool
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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()
    {
        // すべて解放する
        for( pool::iterator it=m_pool.begin(); it != m_pool.end(); )
        {
            value_ptr p = *it;
            it = m_pool.erase(it);
            delete p;
        }
    }
public:
    void push(value_ptr ptr) { m_pool.push_back(ptr); }
public:
    static iuPool& GetInstance() { static iuPool inst; return inst; }
};

}   // 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:
    explicit IParamTestInfoData(const char* name) : m_name(name) {}
    virtual ~IParamTestInfoData() IUTEST_CXX_DEFAULT_FUNCTION
    virtual TestCase* MakeTestCase(const char* , TestTypeId , SetUpMethod , TearDownMethod ) const = 0;
    virtual EachTestBase* RegisterTest(TestCase* , const char* ) const = 0;
    const char* GetName() const { return m_name.c_str(); }
protected:
    ::std::string m_name;
};

/**
 * @brief   パラメータ単体テストインスタンスインターフェイス
*/
class IParamTestCaseInfo
{
public:
    virtual ~IParamTestCaseInfo() {}
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() const
    {
        for( TestInfoContainer::const_iterator it=m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
        {
            OnRegisterTests(*it);
        }
    }

    ::std::string GetTestCaseBaseName() const { return m_testcase_base_name; }
    ::std::string GetPackageName()      const { return m_package_name; }

public:
    bool is_same(const ::std::string& base_name, const ::std::string& package_name)
    {
        return m_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)();
    typedef ::std::string (*pfnParamNameGeneratorFunc)(const TestParamInfo<ParamType>&);

    class Functor
    {
    public:
        Functor()
            : CreateGen(NULL), ParamNameGen(NULL) {}
        Functor(pfnCreateGeneratorFunc c, pfnParamNameGeneratorFunc p)
            : CreateGen(c), ParamNameGen(p) {}
        pfnCreateGeneratorFunc      CreateGen;
        pfnParamNameGeneratorFunc   ParamNameGen;
    };

public:
    /// コンストラクタ
    ParamTestCaseInfo(const ::std::string& testcase_name, const ::std::string& package_name)
        : IParamTestCaseInfo(testcase_name, package_name)
    {
    }
    virtual ~ParamTestCaseInfo() {}

    /**
     * @brief   インスタンスの登録
    */
    int AddTestCaseInstantiation(::std::string name
        , pfnCreateGeneratorFunc create_func, pfnParamNameGeneratorFunc paramname_func)
    {
#if IUTEST_HAS_STD_EMPLACE
        m_instantiation.emplace_back(name, Functor(create_func, paramname_func));
#else
        m_instantiation.push_back(InstantiationPair(name, Functor(create_func, paramname_func)));
#endif
        return 0;
    }

    /**
     * @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.CreateGen)());

            ::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 )
            {
                size_t i=0;
                for( p->Begin(); !p->IsEnd(); p->Next() )
                {
                    const ::std::string name = MakeParamTestName(infodata->GetName()
                        , gen_it->second.ParamNameGen(TestParamInfo<ParamType>(p->GetCurrent(), i)) );
#if 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;
                }
            }
        }
    }

    static ::std::string DefaultParamNameFunc(const TestParamInfo<ParamType>& info)
    {
        return Tester::MakeTestParamName(info);
    }

    template<typename ParamNameFunctor>
    static ParamNameFunctor GetParamNameGen(ParamNameFunctor func)
    {
        return func;
    }

    static pfnParamNameGeneratorFunc GetParamNameGen()
    {
        return DefaultParamNameFunc;
    }

private:
    static bool CheckTestName(const TestCase* testcase, const::std::string& name)
    {
        const int count = testcase->total_test_count();
        for(int i = 0; i < count; ++i )
        {
            if( detail::IsStringEqual(name.c_str(), testcase->GetTestInfo(i)->name()) )
            {
                return false;
            }
        }
        return true;
    }
private:
    typedef ::std::pair< ::std::string, Functor > InstantiationPair;
    typedef ::std::vector<InstantiationPair> InstantiationContainer;
    InstantiationContainer m_instantiation;
};

/**
 * @brief   パラメータテストパターン保管庫
*/
class ParamTestCaseHolder
{
private:
    ~ParamTestCaseHolder()
    {
        // 解放
        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() const { return m_testcase_infos.size(); }

private:
    struct RegisterTestsFunctor
    {
        inline void operator ()(const IParamTestCaseInfo* p) const
        {
            p->RegisterTests();
        }
    };

    // テストを登録
    void RegisterTests()
    {
        ::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() { static UnitTest inst; return inst; }
    /**
     * @brief   UnitTest インスタンスの取得
    */
    static UnitTest* GetInstance() { return &instance(); }

public:
    /**
     * @brief   テスト中の TestCase の取得
    */
    const TestCase*     current_test_case() const { return m_current_testcase; }

    /**
     * @brief   テスト中の TestInfo の取得
     * @note    互換性のため メンバ関数 にしています。
    */
    const TestInfo*     current_test_info() const { return Test::GetCurrentTestInfo(); }

    
    unsigned int        random_seed()       const { return TestEnv::current_random_seed(); }

    
    int                 repeat_counter()    const IUTEST_CXX_NOEXCEPT_SPEC { return m_repeat_counter; }

    
    int                 repeat_count()      const IUTEST_CXX_NOEXCEPT_SPEC { return TestEnv::get_repeat_count(); }

public:
    
    int             total_test_count()      const IUTEST_CXX_NOEXCEPT_SPEC { return m_total_test_num; }
    
    int             reportable_test_count() const;
    
    int             test_to_run_count()     const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num; }
    
    int             failed_test_count()     const;
    
    int             disabled_test_count()   const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable_num; }
    
    int             reportable_disabled_test_count() const;
    
    int             successful_test_count() const;
    
    int             skip_test_count()       const;
    
    int             reportable_skip_test_count() const;
    
    int             test_run_skipped_count() const;
    
    int             reportable_test_run_skipped_count() const;

    
    int             total_test_case_count() const { return m_testcases.size(); }
    
    int             test_case_to_run_count() const;
    
    int             successful_test_case_count() const;
    
    int             failed_test_case_count() const;

    
    const TestResult* ad_hoc_testresult() const IUTEST_CXX_NOEXCEPT_SPEC { return &m_ad_hoc_testresult; }

    
    TimeInMillisec  elapsed_time()      const IUTEST_CXX_NOEXCEPT_SPEC { return m_elapsedmsec; }

    
    TimeInMillisec  start_timestamp()   const IUTEST_CXX_NOEXCEPT_SPEC { return m_start_timestamp; }

    
    const TestCase* GetTestCase(int index)  const { return m_testcases[index]; }

    
    bool            Passed()            const;
    
    bool            Failed()            const { return !Passed(); }

    
    TestEventListeners& listeners()     const { return TestEnv::event_listeners(); }

protected:
    /**
     * @brief   テストの実行
    */
    int Run();

private:
#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
    int RunOnMSC();
#endif
    int RunImpl();

    /**
     * @brief   テストの実行（１ループ）
    */
    bool RunOnce();

private:
    /**
     * @brief   プログラムの開始
    */
    void TestProgramStart();

    /**
     * @brief   イテレーション毎のセットアップ
    */
    void SetUpTestIteration();

    /**
     * @brief   環境セットアップ
    */
    void EnvironmentSetUp();

    /**
     * @brief   環境解除
    */
    void EnvironmentTearDown();

    /**
     * @brief   プログラムの終了
    */
    void TestProgramEnd();

private:
    // C言語の終了コールバック関数
    static void OnExit()
    {
        instance().TestProgramEnd();
    }

private:
    UnitTest()
        : m_repeat_counter(0)
        , m_init_iutest_count(0)
        , m_test_started(false)
        , m_start_timestamp(0)
    {
        // デフォルトリポーターをセット
        TestEnv::SetGlobalTestPartResultReporter(&m_default_test_part_result_reporter);
        // 環境変数によるテストフラグ指定をロード
        TestEnv::LoadEnvironmentVariable();
    }
#if defined(_MSC_VER) && _MSC_VER < 1300
public: // VC++6.0 bug
#endif
    ~UnitTest()
    {
        TestEnv::ReleaseGlobalTestEnvironment();
        TestEnv::SetGlobalTestPartResultReporter(NULL);
    }

private:
    // 初期化処理
    void Initialize();

#if IUTEST_HAS_PARAM_TEST
public:
    
    detail::ParamTestCaseHolder& parameterized_test_registry() 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-2017, 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() const
{
    return detail::SumOverList(m_testcases, &TestCase::reportable_test_count);
}

IUTEST_IPP_INLINE int UnitTest::failed_test_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::failed_test_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_disabled_test_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::reportable_disabled_test_count);
}

IUTEST_IPP_INLINE int UnitTest::successful_test_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::successful_test_count);
}

IUTEST_IPP_INLINE int UnitTest::skip_test_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::skip_test_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_skip_test_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::reportable_skip_test_count);
}

IUTEST_IPP_INLINE int UnitTest::test_run_skipped_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::test_run_skipped_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_test_run_skipped_count() const
{
    return detail::SumOverList(m_testcases, &TestCase::reportable_test_run_skipped_count);
}

IUTEST_IPP_INLINE int UnitTest::test_case_to_run_count() const
{
    return detail::CountIfOverList(m_testcases, &TestCase::should_run);
}

IUTEST_IPP_INLINE int UnitTest::successful_test_case_count() const
{
    return detail::CountIfOverList(m_testcases, &TestCase::Passed);
}

IUTEST_IPP_INLINE int UnitTest::failed_test_case_count() const
{
    return detail::CountIfOverList(m_testcases, &TestCase::Failed);
}

IUTEST_IPP_INLINE bool UnitTest::Passed() const
{
    if( m_ad_hoc_testresult.Failed() )
    {
        return false;
    }
    for( iuTestCases::const_iterator it=m_testcases.begin(), end=m_testcases.end(); it != end; ++it )
    {
        if( (it)->Failed() )
        {
            return false;
        }
    }
    return true;
}

IUTEST_IPP_INLINE int UnitTest::Run()
{
    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;
    }

#if IUTEST_HAS_EXCEPTIONS
    if( TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_GLOBAL) )
    {
        int ret = 1;
        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( ... )
        {
        }
        return ret;
    }
#endif
    return RunImpl();
}

#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
IUTEST_IPP_INLINE int UnitTest::RunOnMSC()
{
    _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()
{
    m_repeat_counter = 0;
    int repeat = TestEnv::get_repeat_count();
    bool result = true;
    if( repeat != 0 )
    {
        m_start_timestamp = detail::GetTimeInMillis();
        TestProgramStart();

        while( repeat )
        {
            SetUpTestIteration();

            listeners().OnTestIterationStart(*this, m_repeat_counter);
            if( !RunOnce() )
            {
                result = false;
            }
            listeners().OnTestIterationEnd(*this, m_repeat_counter);

            ++m_repeat_counter;
            if( repeat > 0 )
            {
                --repeat;
            }
        }

        TestProgramEnd();
    }
    if( !result )
    {
        return 1;
    }
    if( detail::IUTestLog::HasError() )
    {
        return 1;
    }
    if( IUTEST_FLAG(warning_into_error) )
    {
        if( detail::IUTestLog::HasWarning() )
        {
            return 1;
        }
    }
    return 0;
}

IUTEST_IPP_INLINE bool UnitTest::RunOnce()
{
    m_elapsedmsec = 0;

    // テスト結果のクリア
    ClearNonAdHocTestResult();

    // 実行対象のテストがない場合は何もしない
    if( test_to_run_count() == 0 )
    {
        return Passed();
    }

    // シャッフル
    if( TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS) )
    {
        detail::RandomShuffle(m_testcases, TestEnv::genrand());
    }

    // グローバル環境セット
    EnvironmentSetUp();

    if( m_ad_hoc_testresult.HasFatalFailure() )
    {
        return false;
    }

    {
        detail::iuStopWatch sw;
        sw.start();
        for( iuTestCases::iterator it=m_testcases.begin(), end=m_testcases.end(); it != end; ++it )
        {
            m_current_testcase = it;
            (it)->Run();
            m_current_testcase = NULL;
        }
        m_elapsedmsec = sw.stop();
    }

    // グローバル環境セット
    EnvironmentTearDown();

    return Passed();
}

IUTEST_IPP_INLINE void UnitTest::TestProgramStart()
{
//#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

    // フィルタリング
    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_STD_QUICK_EXIT
    ::std::at_quick_exit(OnExit);
#endif

    m_test_started = true;

    listeners().OnTestProgramStart(*this);
}

IUTEST_IPP_INLINE void UnitTest::SetUpTestIteration()
{
    TestEnv::SetUp();
}

IUTEST_IPP_INLINE void UnitTest::EnvironmentSetUp()
{
    listeners().OnEnvironmentsSetUpStart(*this);
    for( iuEnvironmentList::iterator it = TestEnv::environments().begin(), end=TestEnv::environments().end(); it != end; ++it )
    {
        (*it)->SetUp();
    }
    listeners().OnEnvironmentsSetUpEnd(*this);
}

IUTEST_IPP_INLINE void UnitTest::EnvironmentTearDown()
{
    listeners().OnEnvironmentsTearDownStart(*this);
    for( iuEnvironmentList::reverse_iterator it = TestEnv::environments().rbegin(), end=TestEnv::environments().rend(); it != end; ++it )
    {
        (*it)->TearDown();
    }
    listeners().OnEnvironmentsTearDownEnd(*this);
}

IUTEST_IPP_INLINE void UnitTest::TestProgramEnd()
{
    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()
{
    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-2016, 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-2016, 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() : content(NULL) {}
    template<typename T>
    any(const T& rhs) : content(new holder<T>(rhs)) {}  // NOLINT
    any(const any& rhs) : content(rhs.content == NULL ? NULL : rhs.content->clone()) {}
    ~any() { delete content; }
public:
    /**
     * @brief   swap
    */
    any& swap(any& rhs)
    {
        ::std::swap(content, rhs.content);
        return *this;
    }
    /**
     * @brief   空かどうか
     * @retval  true = 空
    */
    bool empty() const
    {
        return content == NULL;
    }
    /**
     * @brief   要素のクリア
    */
    void clear()
    {
        any().swap(*this);
    }
    /**
     * @brief   型IDの取得
     * @return  型ID
    */
    type_id type() const
    {
        return content == NULL ? internal::GetTypeId<void>() : content->type();
    }
    /**
     * @brief   型の比較
     * @retval  true = 同一
    */
    template<typename T>
    bool type_equal() 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() const = 0;
        virtual placeholder* clone() const = 0;
    };
    template<typename T>
    class holder : public placeholder
    {
    public:
        explicit holder(const T& v) : held(v) {}
    public:
        virtual type_id type() const IUTEST_CXX_OVERRIDE
        {
            return internal::GetTypeId<T>();
        }
        virtual placeholder* clone() 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 ...
 * @param   ...             = Param name generator function (option)
*/
#if IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR
#  define IUTEST_INSTANTIATE_TEST_CASE_P(prefix_, testfixture_, generator_, ...)    \
    IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testfixture_, generator_, __VA_ARGS__)
#else
#  define IUTEST_INSTANTIATE_TEST_CASE_P(prefix_, testfixture_, generator_)         \
    IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testfixture_, generator_)
#endif

/**
 * @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_)       IUTEST_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(testcase_, iuTestWithAny), 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_) \
    IUTEST_TEST_P_(IUTEST_ALIAS_TESTNAME_F(testcase_, iuTestWithAny), 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   パラメータテスト登録
*/
#if IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR
#  define IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testcase_, generator_, ...)        \
    IIUT_INSTANTIATE_TEST_CASE_P_I(prefix_, testcase_, generator_, GetParamNameGen(__VA_ARGS__))
#else
#  define IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testcase_, generator_)             \
    IIUT_INSTANTIATE_TEST_CASE_P_I(prefix_, testcase_, generator_, GetParamNameGen())
#endif

#if IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE

#define IIUT_INSTANTIATE_TEST_CASE_P_I(prefix_, testcase_, generator_, paramname_generator_)        \
    IIUT_INSTANTIATE_TEST_CASE_P_II(prefix_, IUTEST_PP_IF( IUTEST_PP_IS_BEGIN_PARENS(testcase_)     \
        , IUTEST_ALIAS_TESTNAME_F_, IUTEST_PP_EMPTY() ) testcase_, generator_, paramname_generator_)

#else

#define IIUT_INSTANTIATE_TEST_CASE_P_I(prefix_, testcase_, generator_, paramname_generator_)        \
    IIUT_INSTANTIATE_TEST_CASE_P_II(prefix_, testcase_, generator_, paramname_generator_)

#endif

#define IIUT_INSTANTIATE_TEST_CASE_P_II(prefix_, testcase_, generator_, paramname_generator_)       \
    IIUT_INSTANTIATE_TEST_CASE_P_III(prefix_, testcase_, IIUT_TEST_P_BASE_FIXTURE(testcase_)        \
        , generator_, paramname_generator_)


#define IIUT_INSTANTIATE_TEST_CASE_P_III(prefix_, testcase_, basefixture_, generator_, paramname_generator_)    \
    IIUT_TEST_P_FIXTURE_DECL_(testcase_)                                                            \
    static ::iutest::detail::iuIParamGenerator< basefixture_::ParamType >*                          \
        IIUT_TEST_P_EVALGENERATOR_NAME_(prefix_, testcase_)() { return generator_; }                \
    static ::std::string IIUT_TEST_P_PARAMGENERATOR_NAME_(prefix_, testcase_)(                      \
        const ::iutest::TestParamInfo< basefixture_::ParamType >& info) { return                    \
             ::iutest::detail::ParamTestCaseInfo< basefixture_ >::paramname_generator_(info); }     \
    int IIUT_TEST_P_INSTANTIATIONREGISTER_NAME_(prefix_, testcase_)() {                             \
        ::iutest::detail::ParamTestCaseInfo< basefixture_ >* p = IIUT_GETTESTCASEPATTERNHOLDER(     \
                basefixture_, IIUT_TO_NAME_STR_(testcase_), IUTEST_GET_PACKAGENAME_());             \
        return p->AddTestCaseInstantiation(#prefix_                                                 \
                    , IIUT_TEST_P_EVALGENERATOR_NAME_(prefix_, testcase_)                           \
                    , IIUT_TEST_P_PARAMGENERATOR_NAME_(prefix_, testcase_) );                       \
    } IIUT_TEST_P_INSTANTIATIONREGISTER_(prefix_, testcase_)

/**
 * @brief   パラメータテストクラス定義
*/
#define IIUT_TEST_P_I_(classname_, testcase_, testcasename_, testname_)                     \
    IIUT_TEST_P_FIXTURE_DECL_(testcase_)                                                    \
    class classname_ : public testcase_ {                                                   \
        public: classname_() {}                                                             \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE;                                 \
        private: static int AddRegister() {                                                 \
            static ::iutest::detail::ParamTestInstance< classname_ > testinfo(testname_);   \
            IIUT_GETTESTCASEPATTERNHOLDER(testcase_, testcasename_                          \
                    , IUTEST_GET_PACKAGENAME_())->AddTestPattern(&testinfo); return 0;      \
        }                                                                                   \
        static int dummy_;                                                                  \
        IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(classname_);                                     \
    };                                                                                      \
    int classname_::dummy_ IUTEST_ATTRIBUTE_UNUSED_  = classname_::AddRegister();           \
    void classname_::Body()

#define IIUT_TEST_P_I_IGNORE_(classname_, testcase_, testcasename_, testname_)              \
    class classname_ : public testcase_ {                                                   \
        public: classname_() {}                                                             \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE { IUTEST_SKIP() << "ignored test..."; }      \
        template<typename T>void Body();                                                    \
        private: static int AddRegister() {                                                 \
            static ::iutest::detail::ParamTestInstance< classname_ > testinfo(testname_);   \
            IIUT_GETTESTCASEPATTERNHOLDER(testcase_, testcasename_                          \
                , IUTEST_GET_PACKAGENAME_())->AddTestPattern(&testinfo); return 0;          \
        }                                                                                   \
        static int dummy_;                                                                  \
        IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(classname_);                                     \
    };                                                                                      \
    int classname_::dummy_ IUTEST_ATTRIBUTE_UNUSED_ = classname_::AddRegister();            \
    template<typename T>void classname_::Body()

#define IIUT_TEST_P_(macro, testcase_, testname_)       \
    macro(IUTEST_TEST_CLASS_NAME_(testcase_, testname_) \
        , IIUT_TEST_P_BASE_FIXTURE(testcase_)           \
        , IIUT_TO_NAME_STR_(testcase_), IIUT_TO_NAME_STR_(testname_))

#if IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE

#define IIUT_TEST_P_A_(macro, testcase_, testname_)                         \
    IIUT_TEST_P_( macro, IUTEST_PP_IF( IUTEST_PP_IS_BEGIN_PARENS(testcase_) \
        , IUTEST_ALIAS_TESTNAME_F_, IUTEST_PP_EMPTY() ) testcase_, testname_)

#define IUTEST_TEST_P_(testcase_, testname_)        \
    IIUT_TEST_P_A_(IIUT_TEST_P_I_, testcase_, testname_)

#define IUTEST_TEST_P_IGNORE_(testcase_, testname_) \
    IIUT_TEST_P_A_(IIUT_TEST_P_I_IGNORE_, testcase_, testname_)


#else

#define IUTEST_TEST_P_(testcase_, testname_)        \
    IIUT_TEST_P_(IIUT_TEST_P_I_, testcase_, testname_)

#define IUTEST_TEST_P_IGNORE_(testcase_, testname_) \
    IIUT_TEST_P_(IIUT_TEST_P_I_IGNORE_, testcase_, testname_)

#endif

#define IIUT_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_##_x_iutest_x_##testcase_##_EvalGenerator_

#define IIUT_TEST_P_PARAMGENERATOR_NAME_(prefix_, testcase_)    IIUT_TEST_P_PARAMGENERATOR_NAME_I(prefix_, IIUT_TO_VARNAME_(testcase_))
#define IIUT_TEST_P_PARAMGENERATOR_NAME_I(prefix_, testcase_)   IIUT_TEST_P_PARAMGENERATOR_NAME_I_(prefix_, testcase_)
#define IIUT_TEST_P_PARAMGENERATOR_NAME_I_(prefix_, testcase_)  s_##prefix_##_x_iutest_x_##testcase_##_ParamGenerator_

#define IIUT_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_##_x_iutest_x_##testcase_##_TestCaseInstantiationRegister

#define IIUT_TEST_P_INSTANTIATIONREGISTER_(prefix_, testcase_)  \
    IIUT_TEST_P_INSTANTIATIONREGISTER_I(prefix_, IIUT_TO_VARNAME_(testcase_), IIUT_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_##_x_iutest_x_##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:
    explicit 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() { return WithParamInterface<any>::GetParam(); }

    /**
     * @brief   パラメータの取得
    */
    template<typename T>
    static T GetParam() { 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=static_cast<T>(1))
{
    return new detail::iuRangeParamsGenerator<T>(begin, end, step);
}

/**
 * @brief   真偽値パラメータ
*/
inline detail::iuParamGenerator<bool> IUTEST_ATTRIBUTE_UNUSED_ Bool()
{
    return new detail::iuBoolParamsGenerator();
}

#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

#if IUTEST_HAS_CSVPARAMS

/**
 * @brief   csv ファイルパラメータ
*/
template<typename T>
detail::iuParamGenerator<T> IUTEST_ATTRIBUTE_UNUSED_ CSV(const char* path, char delimiter = ',')
{
    return new detail::iuCsvFileParamsGenerator<T>(path, delimiter);
}

template<typename T>
detail::iuParamGenerator<T> IUTEST_ATTRIBUTE_UNUSED_ CSV(const char* relative_path, const char* test_file, char delimiter = ',')
{
    const char* sep = detail::FindLastPathSeparator(test_file, strlen(test_file));
    ::std::string path;
    if( sep != NULL )
    {
        const size_t length = ::std::distance(test_file, sep);
        path += ::std::string(test_file, length);
        path += detail::GetPathSeparator();
    }
    path += relative_path;
    return new detail::iuCsvFileParamsGenerator<T>(path, delimiter);
}

#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-2016, 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       typed util
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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       type list
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2016, 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
{

//======================================================================
// 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)

#define IIUT_TEMPLATE_TPARAM1   template<typename XXX> class

/**
 * @brief   TemplateTypeListBind
*/
template<IIUT_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<IIUT_TEMPLATE_TPARAM1 T1, IIUT_TEMPLATE_TPARAM1 ...Types>
struct VariadicTemplateTypeList
{
    typedef TemplateTypeSel<T1> Head;
    typedef VariadicTemplateTypeList<Types...> Tail;
};
template<IIUT_TEMPLATE_TPARAM1 T1>
struct VariadicTemplateTypeList<T1>
{
    typedef TemplateTypeSel<T1> Head;
    typedef TemplateTypeList0 Tail;
};

#else

template<IIUT_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< IIUT_TEMPLATE_TPARAM1 T0, IUTEST_PP_ENUM_SHIFTED_PARAMS(m, IIUT_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<IIUT_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_, IIUT_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, IIUT_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   ...         = タイプリスト
*/
#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_)     IUTEST_TYPED_TEST_(testcase_, testname_)

/**
 * @ingroup TYPED_TEST
 * @def     IUTEST_T(testcase_, testname_)
 * @brief   型付けテスト関数定義マクロ
 * @param   testcase_   = テストケース名
 * @param   testname_   = テスト名
*/
#define IUTEST_T(testcase_, testname_)              IUTEST_TYPED_TEST_(testcase_, testname_)


/**
 * @private
 * @{
*/
#if IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE
#define IIUT_TYPED_TEST_PARAMS_(testcase_)                                          \
    IIUT_TYPED_TEST_PARAMS_I_( IUTEST_PP_IF( IUTEST_PP_IS_BEGIN_PARENS(testcase_)   \
        , IUTEST_ALIAS_TESTNAME_F_, IUTEST_PP_EMPTY() ) testcase_)
#else
#define IIUT_TYPED_TEST_PARAMS_(testcase_)          IIUT_TYPED_TEST_PARAMS_I_(testcase_)
#endif

#define IIUT_TYPED_TEST_PARAMS_I_(testcase_)        IIUT_TYPED_TEST_PARAMS_II_(IIUT_TO_VARNAME_(testcase_))
#define IIUT_TYPED_TEST_PARAMS_II_(testcase_)       IIUT_TYPED_TEST_PARAMS_III_(testcase_)
#define IIUT_TYPED_TEST_PARAMS_III_(testcase_)      iutest_types_params_##testcase_

#if !defined(IUTEST_NO_VARIADIC_MACROS)
#  define IIUT_TYPED_TEST_CASE_(testcase_, ...)     \
    typedef ::iutest::detail::TypeList< __VA_ARGS__ >::type IIUT_TYPED_TEST_PARAMS_(testcase_)
#else
#  define IIUT_TYPED_TEST_CASE_(testcase_, types_)      \
    typedef ::iutest::detail::TypeList< types_ >::type  IIUT_TYPED_TEST_PARAMS_(testcase_)
#endif

#define IIUT_TYPED_TEST_I(classname_, testcase_, testcasename_, testname_)          \
    template<typename iutest_TypeParam> class classname_ : public testcase_<iutest_TypeParam> { \
        typedef testcase_<iutest_TypeParam> TestFixture;                            \
        typedef iutest_TypeParam TypeParam;                                         \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE;                         \
    };                                                                              \
    ::iutest::detail::TypeParamTestInstance< classname_, IIUT_TYPED_TEST_PARAMS_(testcase_) >   \
        IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(                           \
        IUTEST_CONCAT_PACKAGE_(testcasename_), IIUT_TO_NAME_STR_(testname_));       \
    template<typename iutest_TypeParam>                                             \
    void classname_<iutest_TypeParam>::Body()

#define IIUT_TYPED_TEST_I_IGNORE(classname_, testcase_, testcasename_, testname_)   \
    template<typename iutest_TypeParam> class classname_ : public testcase_<iutest_TypeParam> {     \
        typedef testcase_<iutest_TypeParam> TestFixture;                            \
        typedef iutest_TypeParam TypeParam;                                         \
        protected: virtual void Body() IUTEST_CXX_OVERRIDE { IUTEST_SKIP() << "ignored test..."; }  \
        template<typename T>void Body();                                            \
    };                                                                              \
    ::iutest::detail::TypeParamTestInstance< classname_, IIUT_TYPED_TEST_PARAMS_(testcase_) >       \
        IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(                           \
        IUTEST_CONCAT_PACKAGE_(testcasename_), IIUT_TO_NAME_STR_(testname_));       \
    template<typename iutest_TypeParam> template<typename T>                        \
    void classname_<iutest_TypeParam>::Body()

#define IIUT_TYPED_TEST_(macro, testcase_, testname_)                   \
    macro(IUTEST_TEST_CLASS_NAME_(testcase_, testname_)                 \
        , IIUT_TO_VARNAME_(testcase_), IIUT_TO_NAME_(testcase_)         \
        , testname_)

#if IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE

#define IIUT_TYPED_TEST_A_(macro, testcase_, testname_)                         \
    IIUT_TYPED_TEST_( macro, IUTEST_PP_IF( IUTEST_PP_IS_BEGIN_PARENS(testcase_) \
        , IUTEST_ALIAS_TESTNAME_F_, IUTEST_PP_EMPTY() ) testcase_, testname_)

#define IUTEST_TYPED_TEST_(testcase_, testname_)        \
    IIUT_TYPED_TEST_A_(IIUT_TYPED_TEST_I, testcase_, testname_)

#define IUTEST_TYPED_TEST_IGNORE_(testcase_, testname_) \
    IIUT_TYPED_TEST_A_(IIUT_TYPED_TEST_I_IGNORE, testcase_, testname_)

#else

#define IUTEST_TYPED_TEST_(testcase_, testname_)        \
    IIUT_TYPED_TEST_(IIUT_TYPED_TEST_I, testcase_, testname_)

#define IUTEST_TYPED_TEST_IGNORE_(testcase_, testname_) \
    IIUT_TYPED_TEST_(IIUT_TYPED_TEST_I_IGNORE, testcase_, testname_)

#endif

/**
 * @}
*/

#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 IIUT_TYPED_TEST_CASE_PSTATE_NAME_(testcase_)    s_iutest_typed_test_case_p_state_##testcase_##_
#define IIUT_TYPED_TEST_P_NAMESPACE_(testcase_)         iutest_typed_test_case_p_name_##testcase_##_
#define IIUT_TYPED_TEST_P_ADDTESTNAME(testcase_, testname_)                             \
    static const int s_iutest_##testname_##_defined_dummy_  IUTEST_ATTRIBUTE_UNUSED_ =  \
    IIUT_TYPED_TEST_CASE_PSTATE_NAME_(testcase_).AddTestName(__FILE__, __LINE__, #testcase_, #testname_)


#define IIUT_TYPED_TEST_CASE_P_(testcase_)      \
    static ::iutest::detail::TypedTestCasePState    IIUT_TYPED_TEST_CASE_PSTATE_NAME_(testcase_)

#define IIUT_TYPED_TEST_P_(testcase_, testname_)                \
    namespace IIUT_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() IUTEST_CXX_OVERRIDE;     \
    }; IIUT_TYPED_TEST_P_ADDTESTNAME(testcase_, testname_);     \
    }                                                           \
    template<typename iutest_TypeParam>                         \
    void IIUT_TYPED_TEST_P_NAMESPACE_(testcase_)::testname_<iutest_TypeParam>::Body()

#define IIUT_TYPED_TEST_P_IGNORE_(testcase_, testname_)         \
    namespace IIUT_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() IUTEST_CXX_OVERRIDE { IUTEST_SKIP() << "ignored test..."; }      \
        template<typename T>void Body();                        \
    }; IIUT_TYPED_TEST_P_ADDTESTNAME(testcase_, testname_);     \
    }                                                           \
    template<typename iutest_TypeParam>template<typename T>     \
    void IIUT_TYPED_TEST_P_NAMESPACE_(testcase_)::testname_<iutest_TypeParam>::Body()

#define IIUT_REGISTER_TYPED_TEST_CASE_P_(testcase_, ...)                                \
    namespace IIUT_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_ = \
    IIUT_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_              \
        , IIUT_TYPED_TEST_P_NAMESPACE_(testcase_)::iutest_AllTests_         \
        , ::iutest::detail::TypeList< __VA_ARGS__ >::type >::Register(      \
            #prefix_, IIUT_TO_NAME_STR_(testcase_), IUTEST_GET_PACKAGENAME_()   \
        , IIUT_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, size_t index)
            : m_mediator(AddTestCase(testcase, index))
            , m_info(&m_mediator, name, &m_factory)
            , m_next(testcase, name, index+1)
        {
        }

    private:
        static TestCase* AddTestCase(const char* testcase, size_t index)
        {
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
            return UnitTest::instance().AddTestCase<_MyTestCase>(
#else
            return UnitTest::instance().AddTestCase(
#endif
#if IUTEST_HAS_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()
        {
            // 順番通りになるように前から登録
            UnitTest::instance().AddTestInfo(m_mediator.ptr(), &m_info);
            m_next.AddTest();
        }
    private:
        TestCaseMediator            m_mediator;
        TestInfo                    m_info;
        detail::iuFactory<TestBody> m_factory;

        EachTest<typename TT::Tail, void> m_next;
    };

    // 終端
    template<typename DMY>
    class EachTest<detail::TypeList0, DMY>
    {
    public:
        EachTest(const char* , const char* , size_t ) {}
        void AddTest() {}
    };

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() : m_names(NULL) {}
public:
    const char* names() 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_(FATAL) << detail::FormatCompilerIndependentFileLocation(file, line)
                << ": Test \"" << test_name << "\" is find in \"" << test_names
                    << "\". expected whitespace or comma : " << p[len] << "(" << static_cast<int>(p[len]) <<  ")\n";
            }
            IUTEST_LOG_(WARNING) << detail::FormatCompilerIndependentFileLocation(file, line)
                << ": Test \"" << test_name << "\" has not been registered.\n" << "    TestNames: " << test_names;
            ret = false;
        }
        return ret;
#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<template<typename T> class Fixture, typename Tests, typename Types>
class TypeParameterizedTestCase
{
    template<typename TypeParam, typename TestsList>
    class EachTest : public iuIObject
    {
        typedef typename TestsList::Head        TypeSel;
        typedef typename TypeSel::template bind<TypeParam>::type    TestBody;
        typedef detail::iuFactory<TestBody>     Factory;
        typedef EachTest<TypeParam, TestsList>  _Myt;

        EachTest(TestCase* testcase, const 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()
            IUTEST_CHECK_(test_names != NULL);
            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 = ::std::string(str, static_cast<size_t>(comma - str));
                ++comma;
            }
            _Myt* test = new EachTest(testcase, StripTrailingSpace(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, size_t index=0)
    {
#if IUTEST_HAS_EXCEPTIONS
        try
        {
            return Register_(prefix, testcase_name, package_name, names, index);
        }
        catch (const ::std::exception& e)
        {
            IUTEST_LOG_(FATAL) << "IUTEST_INSTANTIATE_TYPED_TEST_CASE_P register tests failed...\n"
                << e.what();
        }
        catch(...)
        {
            IUTEST_LOG_(FATAL) << "IUTEST_INSTANTIATE_TYPED_TEST_CASE_P register tests failed...\n";
        }
        return false;
#else
        return Register_(prefix, testcase_name, package_name, names, index);
#endif
    }

private:
    static bool Register_(const char* prefix, const char* testcase_name
        , const ::std::string& package_name, const char* names, size_t index)
    {
        typedef typename Types::Head    TypeParam;
        typedef typename Tests::Head    Head;
        typedef Fixture<Head>           FixtureClass;
        typedef TypedTestCase<TypeParam>    _MyTestCase;
        TestCase* testcase =
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
            UnitTest::instance().AddTestCase<_MyTestCase>(
#else
            UnitTest::instance().AddTestCase(
#endif
            (package_name +
#if IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME
                detail::MakePrefixedIndexTypedTestName<TypeParam>(prefix, testcase_name, index)
#else
                detail::MakePrefixedIndexTestName(prefix, testcase_name, index)
#endif
            ).c_str()
            , 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<template<typename T> class Fixture, typename Tests>
class TypeParameterizedTestCase<Fixture, Tests, detail::TypeList0>
{
public:
    static bool Register(const char* , const char* 
        , const ::std::string& , const char* , size_t index=0)
    {
        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-2016, 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 !defined(_MSC_VER) || _MSC_VER > 1200

#if IUTEST_HAS_TYPED_TEST

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

#if IUTEST_HAS_TYPED_TEST_P

/**
 * @brief   テストから見えるように fried 登録するための宣言
*/
#define IUTEST_FRIEND_TYPED_TEST_P_DECLARATION(test_case_name, test_name) \
    namespace IIUT_TYPED_TEST_P_NAMESPACE_(test_case_name) { template<typename T>class test_name; }

/**
 * @brief   テストから見えるように fried 登録(IUTEST_TYPED_TEST_P 用)
*/
#define IUTEST_FRIEND_TYPED_TEST_P(test_case_name, test_name) \
    template<typename T>friend class IIUT_TYPED_TEST_P_NAMESPACE_(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< IIUT_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< IIUT_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, IIUT_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 IIUT_PEEP_TAG_NAME_(class_name, member_name);                    \
    template<>struct IIUT_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 IIUT_PEEP_SETTER_NAME_(class_name, member_name) {                                    \
        IIUT_PEEP_SETTER_NAME_(class_name, member_name)() {                                     \
            ::iutest::detail::peep_tag<Tag>::value = X; }                                       \
        static IIUT_PEEP_SETTER_NAME_(class_name, member_name) instance;                        \
    };                                                                                          \
    template<typename T, typename Tag, typename Tag::type X>                                    \
    IIUT_PEEP_SETTER_NAME_(class_name, member_name)<T, Tag, X>                                  \
        IIUT_PEEP_SETTER_NAME_(class_name, member_name)<T, Tag, X>::instance;                   \
    template struct IIUT_PEEP_SETTER_NAME_(class_name, member_name)<class_name                  \
        , IIUT_PEEP_TAG_NAME_(class_name, member_name)<class_name>, &class_name::member_name>

#define IIUT_PEEP_TAG_NAME_(class_name, member_name)        iu_peep_tag_##member_name
#define IIUT_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 () () { 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 peep_member_object_impl&);
    public:
        operator value_type () 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 peep_member_object_impl&);
    public:
        operator value_type () const { return (*m_ptr).*detail::peep_tag<peep_tag>::value; }
        operator value_type& () { return (*m_ptr).*detail::peep_tag<peep_tag>::value; }
        _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() {}
        peep_static_impl(const value_type& value) { *detail::peep_tag<peep_tag>::value = value; }   // NOLINT
        peep_static_impl(const peep_static_impl&) {}
    public:
        operator value_type () const { return *detail::peep_tag<peep_tag>::value; }
        operator value_type& () { return *detail::peep_tag<peep_tag>::value; }
        _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 () { 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:
    //! private メンバーアクセスオブジェクト型
    typedef typename peep_impl<T, peep_type
        , type_traits::is_member_pointer<peep_type>::value >::type type;
};

#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-2016, 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 && IUTEST_HAS_STD_DECLVAL

#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:
    explicit 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() const
    {
        return AssertionResult(result()) << m_result.message();
    }
private:
    bool result() const { return m_result.passed(); }
    const char* message() const { return m_result.message(); }
private:
    AssertionResult m_result;
};

namespace expression_op_helper
{
    template<typename T>
    T operand_result(const T&);
}

/**
 * @brief   expression lhs
 * @tparam  T=type
*/
template<typename T>
class ExpressionLHS
{
    typedef ExpressionLHS<T> _Myt;
public:
#if IUTEST_HAS_RVALUE_REFS
    explicit ExpressionLHS(T&& lhs) : m_lhs( ::std::forward<T>(lhs) )
    {
        AppendMessage(m_lhs);
    }
#else
    explicit ExpressionLHS(T lhs) : m_lhs(lhs)
    {
        AppendMessage(lhs);
    }
#endif
    ExpressionLHS(T lhs, const ::std::string& msg) : m_lhs(lhs), m_message(msg) {}

public:
    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() 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-2016, 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

//======================================================================
// 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() {}
    virtual ::std::string WhichIs() 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: explicit IUTEST_PP_CAT(name, Matcher)(const T& v) : m_expected(v) {}\
    ::std::string WhichIs() 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() 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_PRAGMA_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_PRAGMA_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() 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() 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() 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:
    explicit FloatingPointEqMatcher(const T& value) : m_expected(value) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual) const
    {
        floating_point<T> f2(actual);
        if( m_expected.AlmostEquals(f2) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

    ::std::string WhichIs() const 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:
    explicit NanSensitiveFloatingPointEqMatcher(const T& value) : m_expected(value) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual) const
    {
        floating_point<T> f2(actual);
        if( m_expected.NanSensitiveAlmostEquals(f2) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

    ::std::string WhichIs() const 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:
    explicit 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() 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:
    explicit HasSubstrMatcher(T expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual) const
    {
        if( HasSubstr(actual, m_expected) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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:
    explicit 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() 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:
    explicit EqMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual) const
    {
        if( Equals(actual, m_expected) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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_PRAGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()
        return actual == expected;
IUTEST_PRAGMA_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:
    explicit TypedEqMatcher(T expected) : EqMatcher<T>(m_expected), m_expected(expected) {}
public:
    AssertionResult operator ()(const T& actual)
    {
        return EqMatcher<T>::operator ()(actual);
    }
    template<typename U>
    AssertionResult operator ()(const U&) const;

private:
    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:
    explicit ContainsMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        IUTEST_USING_BEGIN_END();
        if( Contains(begin(actual), end(actual)) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const IUTEST_CXX_OVERRIDE
    {
        iu_global_format_stringstream strm;
        strm << "Contains: " << m_expected;
        return strm.str();
    }
private:
    template<typename Ite>
    bool Contains(Ite begin, Ite end)
    {
        for( Ite it = begin; it != end; ++it )
        {
            if( CastToMatcher(m_expected)(*it) )
            {
                return true;
            }
        }
        return false;
    }

private:
    IUTEST_PP_DISALLOW_ASSIGN(ContainsMatcher);

    T m_expected;
};

/**
 * @brief   Each matcher
*/
template<typename T>
class EachMatcher : public IMatcher
{
public:
    explicit EachMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        IUTEST_USING_BEGIN_END();
        if( Each(begin(actual), end(actual)) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const IUTEST_CXX_OVERRIDE
    {
        iu_global_format_stringstream strm;
        strm << "Each: " << m_expected;
        return strm.str();
    }
private:
    template<typename Ite>
    bool Each(Ite begin, Ite end)
    {
        for( Ite it = begin; it != end; ++it )
        {
            if( !CastToMatcher(m_expected)(*it) )
            {
                return false;
            }
        }
        return true;
    }

private:
    IUTEST_PP_DISALLOW_ASSIGN(EachMatcher);

    T m_expected;
};

/**
 * @brief   ContainerEq matcher
*/
template<typename T>
class ContainerEqMatcher : public IMatcher
{
public:
    explicit ContainerEqMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        IUTEST_USING_BEGIN_END();
        if( Check(begin(m_expected), end(m_expected)
            , begin(actual), end(actual)) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const IUTEST_CXX_OVERRIDE
    {
        iu_global_format_stringstream strm;
        strm << "ContainerEq: " << PrintToString(m_expected);
        strm << " (" << m_whichIs << ")";
        return strm.str();
    }
private:
    template<typename Ite1, typename Ite2>
    bool Check(Ite1 b1, Ite1 e1, Ite2 b2, Ite2 e2)
    {
        size_t elem=0;
        bool result = true;
        Message ar;
        for( elem=0; b1 != e1 && b2 != e2; ++b1, ++b2, ++elem )
        {
            if( !internal::EqHelper<false>::Compare("", "", *b1, *b2) )
            {
                result = false;
                ar << "\nMismatch in a position " << elem << ": "
                    << ::iutest::internal::FormatForComparisonFailureMessage(*b1, *b2)
                    << " vs " << ::iutest::internal::FormatForComparisonFailureMessage(*b2, *b1);
            }
        }
        if( b1 != e1 || b2 != e2 )
        {
            const size_t elem1 = elem + ::std::distance(b1, e1);
            const size_t elem2 = elem + ::std::distance(b2, e2);
            result = false;
            ar << "\nMismatch element : " << elem1 << " vs " << elem2;
        }
        m_whichIs = ar.GetString();
        return result;
    }

private:
    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)
    {
        IUTEST_USING_BEGIN_END();
        if( Check(begin(m_expected), end(m_expected)
            , begin(actual), end(actual)) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const IUTEST_CXX_OVERRIDE
    {
        iu_global_format_stringstream strm;
        strm << "Pointwise: " << m_matcher << ": " << PrintToString(m_expected);
        strm << " (" << m_whichIs << ")";
        return strm.str();
    }
private:
    template<typename Ite1, typename Ite2>
    bool Check(Ite1 b1, Ite1 e1, Ite2 b2, Ite2 e2)
    {
        size_t elem=0;
        bool result = true;
        Message ar;
        for( elem=0; b1 != e1 && b2 != e2; ++b1, ++b2, ++elem )
        {
            const AssertionResult r = m_matcher(*b2, *b1);
            if( r.failed() )
            {
                result = false;
                ar << "\nMismatch in a position " << elem << ": " << r.message();
            }
        }
        if( b1 != e1 || b2 != e2 )
        {
            const size_t elem1 = elem + ::std::distance(b1, e1);
            const size_t elem2 = elem + ::std::distance(b2, e2);
            result = false;
            ar << "\nMismatch element : " << elem1 << " vs " << elem2;
        }
        m_whichIs = ar.GetString();
        return result;
    }

private:
    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() {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        if( (actual).empty() )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const IUTEST_CXX_OVERRIDE
    {
        return "Is Empty";
    }
private:
    IUTEST_PP_DISALLOW_ASSIGN(IsEmptyMatcher);
};


/**
 * @brief   SizeIs matcher
*/
template<typename T>
class SizeIsMatcher : public IMatcher
{
public:
    explicit SizeIsMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        if( Check(actual) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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(size_t index, const T& expected) : m_index(index), m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        if( CastToMatcher(m_expected)(actual[m_index]) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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)
    {
        IUTEST_USING_BEGIN_END();
        return Check(begin(actual), end(actual));
    }

public:
    ::std::string WhichIs() 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 Ite>
    AssertionResult Check(Ite actual_begin, Ite actual_end)
    {
        const size_t actual_cnt = ::std::distance(actual_begin, actual_end);
        const size_t expected_cnt = m_expected.size();
        if( actual_cnt < expected_cnt )
        {
            iu_global_format_stringstream stream;
            stream << "actual argument[" << actual_cnt << "] is less than " << expected_cnt;
            return AssertionFailure() << WhichIs(stream.str());
        }
        if( m_expected_elem_count && actual_cnt > expected_cnt )
        {
            iu_global_format_stringstream stream;
            stream << "actual argument[" << actual_cnt << "] is greater than " << expected_cnt;
            return AssertionFailure() << WhichIs(stream.str());
        }

        Ite it_a=actual_begin;
        typename ::std::vector<T>::iterator it_e=m_expected.begin();
        for( int i=0; it_e != m_expected.end(); ++it_e, ++it_a, ++i )
        {
            if( *it_a != *it_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)
    {
        IUTEST_USING_BEGIN_END();
        return Check<0, tuples::tuple_size<T>::value - 1>(begin(actual), end(actual), matchers);
    }
    template<int N, typename T>
    static ::std::string WhichIs(const T& matchers)
    {
        ::std::string str = "ElementsAre: {";
        str += WhichIs_<T, N, tuples::tuple_size<T>::value-1>(matchers);
        str += "}";
        return str;
    }
private:
    template<int N, int LAST, typename Ite, typename M>
    static AssertionResult Check(Ite it, Ite end, M& matchers)
    {
        const size_t cnt = ::std::distance(it, end);
        if( cnt < LAST+1 )
        {
            return AssertionFailure() << "ElementsAre: argument[" << cnt << "] is less than " << LAST+1;
        }
        return CheckElem<N, LAST>(it, end, matchers);
    }

    template<int N, int LAST, typename Ite, typename M>
    static AssertionResult CheckElem(Ite it, Ite end, M& matchers
        , typename detail::enable_if<N == LAST, void>::type*& = detail::enabler::value)
    {
        for( int index=N; it != end; ++it, ++index )
        {
            AssertionResult ar = CastToMatcher(tuples::get<N>(matchers))(*it);
            if( !ar )
            {
                return AssertionFailure() << WhichIsElem<N>(matchers, index);
            }
        }
        return AssertionSuccess();
    }

    template<int N, int LAST, typename Ite, typename M>
    static AssertionResult CheckElem(Ite it, Ite end, M& matchers
        , typename detail::disable_if<N == LAST, void>::type*& = detail::enabler::value)
    {
        AssertionResult ar = CastToMatcher(tuples::get<N>(matchers))(*it);
        if( ar )
        {
            return CheckElem<N + 1, LAST>(++it, end, matchers);
        }
        return AssertionFailure() << WhichIsElem<N>(matchers, N);
    }

    template<int N, typename T>
    static ::std::string WhichIsElem(const T& matchers, int index)
    {
        iu_global_format_stringstream strm;
        strm << "ElementsAre(" << index << "): " << tuples::get<N>(matchers);
        return strm.str();
    }

    template<typename T, int N, int LAST>
    static ::std::string WhichIs_(const T& matchers
        , typename detail::enable_if<N == LAST, void>::type*& = detail::enabler::value)
    {
        return StreamableToString(tuples::get<N>(matchers));
    }
    template<typename T, int N, int LAST>
    static ::std::string WhichIs_(const T& matchers
        , typename detail::disable_if<N == LAST, void>::type*& = detail::enabler::value)
    {
        return StreamableToString(tuples::get<N>(matchers)) + ", " + WhichIs_<T, N + 1, LAST>(matchers);
    }
    IUTEST_PP_DISALLOW_ASSIGN(ElementsAreMatcherBase);
};

#if IUTEST_HAS_VARIADIC_TEMPLATES

/**
* @brief    ElementsAre matcher
*/
template<typename ...T>
class ElementsAreMatcher : public ElementsAreMatcherBase
{
public:
    explicit ElementsAreMatcher(T... t) : m_matchers(t...) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        return Check(m_matchers, actual);
    }
    ::std::string WhichIs() const 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() 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() 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() 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() 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:
    explicit KeyMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual) const
    {
        if( CastToMatcher(m_expected)(actual.first) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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() 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() 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:
    explicit PointeeMatcher(const T& expected) : m_expected(expected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        if( Check(actual) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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:
    explicit NotMatcher(const T& unexpected) : m_unexpected(unexpected) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        if( !CastToMatcher(m_unexpected)(actual) )
        {
            return AssertionSuccess();
        }
        return AssertionFailure() << WhichIs();
    }

public:
    ::std::string WhichIs() const 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() {}
public:
    AssertionResult operator ()(const T&) const
    {
        return AssertionSuccess();
    }
    template<typename U>
    AssertionResult operator ()(const U&) const;

public:
    ::std::string WhichIs() 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() {}
public:
    template<typename U>
    AssertionResult operator ()(const U&) const
    {
        return AssertionSuccess();
    }

public:
    ::std::string WhichIs() 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() 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:
    explicit AllOfMatcher(T... t) : m_matchers(t...) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        return Check(m_matchers, actual);
    }
    ::std::string WhichIs() const 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() 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() 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:
    explicit AnyOfMatcher(T... t) : m_matchers(t...) {}

public:
    template<typename U>
    AssertionResult operator ()(const U& actual)
    {
        return Check(m_matchers, actual);
    }
    ::std::string WhichIs() const 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() 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() 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

/** 
 * @brief iutest matchers namespace
*/
namespace matchers
{

/**
 * @defgroup    MATCHERS    Matchers
 * @brief       Matchers
 * @{
*/

/**
 * @brief   Make Equals matcher
 * @details argument == expected
*/
template<typename T>
detail::EqMatcher<T> Equals(const T& expected)
{
    return detail::EqMatcher<T>(expected);
}

/**
 * @brief   Make Eq matcher
 * @details argument == expected
*/
template<typename T>
detail::EqMatcher<T> Eq(const T& expected)
{
    return detail::EqMatcher<T>(expected);
}

/**
 * @brief   Make Ne matcher
 * @details argument != expected
*/
template<typename T>
detail::NeMatcher<T> Ne(const T& expected)
{
    return detail::NeMatcher<T>(expected);
}

/**
 * @brief   Make Le matcher
 * @details argument <= expected
*/
template<typename T>
detail::LeMatcher<T> Le(const T& expected)
{
    return detail::LeMatcher<T>(expected);
}

/**
 * @brief   Make Lt matcher
 * @details argument < expected
*/
template<typename T>
detail::LtMatcher<T> Lt(const T& expected)
{
    return detail::LtMatcher<T>(expected);
}

/**
 * @brief   Make Ge matcher
 * @details argument >= expected
*/
template<typename T>
detail::GeMatcher<T> Ge(const T& expected)
{
    return detail::GeMatcher<T>(expected);
}

/**
 * @brief   Make Gt matcher
 * @details argument > expected
*/
template<typename T>
detail::GtMatcher<T> Gt(const T& expected)
{
    return detail::GtMatcher<T>(expected);
}

/**
 * @brief   Make Twofold Eq matcher
 * @details argument == expected
*/
inline detail::TwofoldEqMatcher Eq()
{
    return detail::TwofoldEqMatcher();
}

/**
 * @brief   Make Twofold Ne matcher
 * @details argument != expected
*/
inline detail::TwofoldNeMatcher Ne()
{
    return detail::TwofoldNeMatcher();
}

/**
 * @brief   Make Twofold Le matcher
 * @details argument <= expected
*/
inline detail::TwofoldLeMatcher Le()
{
    return detail::TwofoldLeMatcher();
}

/**
 * @brief   Make Twofold Lt matcher
 * @details argument < expected
*/
inline detail::TwofoldLtMatcher Lt()
{
    return detail::TwofoldLtMatcher();
}

/**
 * @brief   Make Twofold Ge matcher
 * @details argument >= expected
*/
inline detail::TwofoldGeMatcher Ge()
{
    return detail::TwofoldGeMatcher();
}

/**
 * @brief   Make Twofold Gt matcher
 * @details argument > expected
*/
inline detail::TwofoldGtMatcher Gt()
{
    return detail::TwofoldGtMatcher();
}

/**
 * @brief   Make IsNull matcher
 * @details argument == nullptr
*/
inline detail::IsNullMatcher IsNull()
{
    return detail::IsNullMatcher();
}

/**
 * @brief   Make NotNull matcher
 * @details argument != nullptr
*/
inline detail::NotNullMatcher NotNull()
{
    return detail::NotNullMatcher();
}

/**
 * @brief   Make TypedEq matcher
 * @details argument == expected
*/
template<typename T, typename U>
detail::TypedEqMatcher<T> TypedEq(const U& expected)
{
    return detail::TypedEqMatcher<T>(expected);
}

/**
 * @brief   Make Float Eq matcher
 * @details argument は expected とおよそ等しい
*/
inline detail::FloatingPointEqMatcher<float> FloatEq(float expected)
{
    return detail::FloatingPointEqMatcher<float>(expected);
}

/**
 * @brief   Make Double Eq matcher
 * @details argument は expected とおよそ等しい
*/
inline detail::FloatingPointEqMatcher<double> DoubleEq(double expected)
{
    return detail::FloatingPointEqMatcher<double>(expected);
}

/**
 * @brief   Make NanSensitive Float Eq matcher
 * @details argument は expected とおよそ等しい（NaN 同士は等しいとされる）
*/
inline detail::NanSensitiveFloatingPointEqMatcher<float> NanSensitiveFloatEq(float expected)
{
    return detail::NanSensitiveFloatingPointEqMatcher<float>(expected);
}

/**
 * @brief   Make NanSensitive Double Eq matcher
 * @details argument は expected とおよそ等しい（NaN 同士は等しいとされる）
*/
inline detail::NanSensitiveFloatingPointEqMatcher<double> NanSensitiveDoubleEq(double expected)
{
    return detail::NanSensitiveFloatingPointEqMatcher<double>(expected);
}

/**
 * @brief   Make StrEq matcher
 * @details argument == expected
*/
template<typename T>
detail::StrEqMatcher<T> StrEq(const T& expected)
{
    return detail::StrEqMatcher<T>(expected);
}

/**
 * @brief   Make StrNe matcher
 * @details argument != expected
*/
template<typename T>
detail::StrNeMatcher<T> StrNe(const T& expected)
{
    return detail::StrNeMatcher<T>(expected);
}

/**
 * @brief   Make StrCaseEq matcher
 * @details argument == expected (ignore case)
*/
template<typename T>
detail::StrCaseEqMatcher<T> StrCaseEq(const T& expected)
{
    return detail::StrCaseEqMatcher<T>(expected);
}

/**
 * @brief   Make StrCaseNe matcher
 * @details argument != expected (ignore case)
*/
template<typename T>
detail::StrCaseNeMatcher<T> StrCaseNe(const T& expected)
{
    return detail::StrCaseNeMatcher<T>(expected);
}

/**
 * @brief   Make StartsWith matcher
 * @details argument の先頭が str である
*/
template<typename T>
detail::StartsWithMatcher<const T&> StartsWith(const T& str)
{
    return detail::StartsWithMatcher<const T&>(str);
}

/**
 * @brief   Make HasSubstr matcher
 * @details argument が str を含む
*/
template<typename T>
detail::HasSubstrMatcher<const T&> HasSubstr(const T& str)
{
    return detail::HasSubstrMatcher<const T&>(str);
}

/**
 * @brief   Make EndsWith matcher
 * @details argument の末尾が str である
*/
template<typename T>
detail::EndsWithMatcher<const T&> EndsWith(const T& str)
{
    return detail::EndsWithMatcher<const T&>(str);
}

/**
 * @brief   Make Contains matcher
 * @details argument は expected にマッチする要素を含む
*/
template<typename T>
detail::ContainsMatcher<T> Contains(const T& expected)
{
    return detail::ContainsMatcher<T>(expected);
}

/**
 * @brief   Make Each matcher
 * @details argument はすべての要素が expected にマッチする
*/
template<typename T>
detail::EachMatcher<T> Each(const T& expected)
{
    return detail::EachMatcher<T>(expected);
}

/**
 * @brief   Make ContainerEq matcher
 * @details argument コンテナは expected コンテナにマッチする
*/
template<typename T>
detail::ContainerEqMatcher<T> ContainerEq(const T& expected)
{
    return detail::ContainerEqMatcher<T>(expected);
}

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

/**
 * @brief   Make IsEmpty matcher
 * @details argument.empty()
*/
inline detail::IsEmptyMatcher IsEmpty()
{
    return detail::IsEmptyMatcher();
}

/**
 * @brief   Make SizeIs matcher
 * @details argument の要素数が expected にマッチする
*/
template<typename T>
detail::SizeIsMatcher<T> SizeIs(const T& expected)
{
    return detail::SizeIsMatcher<T>(expected);
}

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

/**
 * @brief   Make ElementsAreArray matcher
 * @details argument はの各要素が a の要素とマッチする
*/
template<typename Container>
detail::ElementsAreArrayMatcher< typename Container::value_type > ElementsAreArray(const Container& container)
{
    IUTEST_USING_BEGIN_END();
    return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(), container.end());
}

#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

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

/**
 * @brief   Make ElementsAreArrayForward matcher
 * @details argument はの各要素が a の要素とマッチする
*/
template<typename Container>
detail::ElementsAreArrayMatcher< typename Container::value_type > ElementsAreArrayForward(const Container& container)
{
    return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(), container.end(), false);
}

#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

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

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

/**
 * @brief   Make Key matcher
 * @details argument.first は expedted にマッチする 
*/
template<typename T>
detail::KeyMatcher<T> Key(const T& expected)
{
    return detail::KeyMatcher<T>(expected);
}

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

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

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

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

/**
 * @brief   Make Pointee matcher
*/
template<typename T>
detail::PointeeMatcher<T> Pointee(const T& expected)
{
    return detail::PointeeMatcher<T>(expected);
}

/**
 * @brief   Make Not matcher
*/
template<typename T>
detail::NotMatcher<T> Not(const T& unexpected)
{
    return detail::NotMatcher<T>(unexpected);
}

/**
 * @brief   Make Any matcher
*/
template<typename T>
detail::AnyMatcher<T> A()
{
    return detail::AnyMatcher<T>();
}


/**
 * @brief   Anything matcher
*/
const detail::AnythingMatcher _;

#if IUTEST_HAS_MATCHER_REGEX

/**
 * @brief   Make MatchesRegex matcher
*/
inline detail::RegexMatcher MatchesRegex(const ::std::string& str)
{
    return detail::RegexMatcher(detail::iuRegex(str), true);
}

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

/**
 * @brief   Make AllOf matcher
 * @details argument が全ての matcher にマッチする
*/
template<typename ...T>
detail::AllOfMatcher<T...> AllOf(const T&... m)
{
    return detail::AllOfMatcher<T...>(m...);
}

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

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

}   // 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-2017, 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

namespace iutest
{

namespace detail
{
    template<typename T1, typename T2>
    struct StaticAssertTypeEqHelper;
}

/**
 * @ingroup IUTEST_UTIL
 * @brief   型アサーション
*/
template<typename T1, typename T2>
static bool StaticAssertTypeEq()
{
    return detail::StaticAssertTypeEqHelper<T1, T2>();
}

}   // end of namespace iutest

#else

/**
 * @ingroup IUTEST_UTIL
 * @brief   型アサーション
 * @note    マクロバージョン
 *          エラーが呼び出し位置に出る
*/
#define StaticAssertTypeEq  detail::StaticAssertTypeEqHelper

#endif

#endif

/**
 * @brief   static_assert
*/
#if IUTEST_HAS_STATIC_ASSERT
#if defined(_MSC_VER) || (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
#  define IUTEST_STATIC_ASSERT_MSG(B, Msg)  static_assert(B, "static_assert: " Msg)
#else
#  define IUTEST_STATIC_ASSERT_MSG(B, Msg)  static_assert(B, Msg)
#endif
#else
#  define IIUT_STATIC_ASSERT_SIZECHECK(B)   sizeof(::iutest::detail::static_assert_failure< (bool)B >)  // NOLINT
#  define IUTEST_STATIC_ASSERT_MSG(B, Msg)                                              \
    typedef ::iutest::detail::StaticAssertionTest< IIUT_STATIC_ASSERT_SIZECHECK(B) >    \
        IUTEST_PP_CAT(iutest_static_assert_typedef_, IUTEST_PP_COUNTER) IUTEST_ATTRIBUTE_UNUSED_
#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() 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-2016, 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_)       \
    IUTEST_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_)  \
    IUTEST_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-2016, 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 DefaultResultPrintListener : public TestEventListener
{
public:
    DefaultResultPrintListener() {}

    virtual ~DefaultResultPrintListener()
    {
        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-2016, 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 DefaultResultPrintListener::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 DefaultResultPrintListener::OnTestIterationStart(const UnitTest& test
                                , int iteration)
{
    if( test.repeat_count() != 1 )
    {
        detail::iuConsole::output("\nRepeating all tests (iteration %d) . . .\n\n", iteration+1);
    }
    // シャッフルテスト
    if( TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS) )
    {
        detail::iuConsole::color_output(detail::iuConsole::yellow, "Note: Randomizing tests' orders with a seed of %u\n", test.random_seed());
    }
    detail::iuConsole::color_output(detail::iuConsole::green, "[==========] ");
    detail::iuConsole::output("Running %d tests from %d test cases.\n", test.test_to_run_count(), test.test_case_to_run_count() );
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::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 DefaultResultPrintListener::OnEnvironmentsSetUpEnd(const UnitTest& test)
{
    IUTEST_UNUSED_VAR(test);
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::OnTestCaseStart(const TestCase& test_case)
{
    detail::iuConsole::color_output(detail::iuConsole::green, "[----------] ");
    detail::iuConsole::output("%d tests from %s\n", test_case.test_to_run_count(), test_case.testcase_name_with_where().c_str() );
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::OnTestStart(const TestInfo& test_info)
{
    detail::iuConsole::color_output(detail::iuConsole::green, "[ RUN      ] ");
    detail::iuConsole::output("%s.%s\n", test_info.test_case_name(), test_info.name());
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::OnTestPartResult(const TestPartResult& test_part_result)
{
    //if( test_part_result.type() == TestPartResult::kSuccess ) return;
#if defined(_MSC_VER) && !defined(IUTEST_OS_WINDOWS_MOBILE)
    OutputDebugStringA(test_part_result.make_newline_message().c_str());
#endif
    detail::iuConsole::output(test_part_result.make_newline_message().c_str());
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::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 DefaultResultPrintListener::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)" );
#else
        detail::iuConsole::output(" (%dms)", test_info.elapsed_time());
#endif
    }
    detail::iuConsole::output("\n");
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::OnTestCaseEnd(const TestCase& test_case)
{
    detail::iuConsole::color_output(detail::iuConsole::green, "[----------] ");
    detail::iuConsole::output("%d tests from %s", test_case.test_to_run_count(), test_case.name() );
    if( TestFlag::IsEnableFlag(TestFlag::PRINT_TIME) )
    {
#if defined(IUTEST_NOT_SUPPORT_STOPWATCH)
        detail::iuConsole::output("(--ms total)");
#else
        detail::iuConsole::output("(%dms total)", test_case.elapsed_time() );
#endif
    }
    detail::iuConsole::output("\n\n");
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::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 DefaultResultPrintListener::OnEnvironmentsTearDownEnd(const UnitTest& test)
{
    IUTEST_UNUSED_VAR(test);
}
IUTEST_IPP_INLINE void DefaultResultPrintListener::OnTestIterationEnd(const UnitTest& test
                                , int iteration)
{
    IUTEST_UNUSED_VAR(iteration);

    detail::iuConsole::color_output(detail::iuConsole::green, "[==========] ");
    detail::iuConsole::output("%d tests from %d testcase ran."
        , test.test_to_run_count(), test.test_case_to_run_count() );
    if( TestFlag::IsEnableFlag(TestFlag::PRINT_TIME) )
    {
#if defined(IUTEST_NOT_SUPPORT_STOPWATCH)
        detail::iuConsole::output(" (--ms total)");
#else
        detail::iuConsole::output(" (%dms total)", test.elapsed_time() );
#endif
    }
    detail::iuConsole::output("\n");

    {
        {
            detail::iuConsole::color_output(detail::iuConsole::green, "[  PASSED  ] ");
            detail::iuConsole::output("%d tests.\n", test.successful_test_count() );
        }
        {
            const int count = test.reportable_disabled_test_count();
            if( !TestFlag::IsEnableFlag(TestFlag::RUN_DISABLED_TESTS) && count > 0 )
            {
                detail::iuConsole::color_output(detail::iuConsole::yellow, "[ DISABLED ] ");
                detail::iuConsole::output("%d tests.\n", count );
                if( TestFlag::IsEnableFlag(TestFlag::VERBOSE) )
                {
                    for( int i=0, case_count=test.total_test_case_count(); i < case_count; ++i )
                    {
                        const TestCase* testcase = test.GetTestCase(i);
                        for( int j=0, info_count=testcase->total_test_count(); j < info_count; ++j )
                        {
                            const TestInfo* testinfo = testcase->GetTestInfo(j);
                            if( testinfo->is_disabled_test() )
                            {
                                detail::iuConsole::color_output(detail::iuConsole::yellow, "[ DISABLED ] ");
                                detail::iuConsole::output("%s.%s\n", testinfo->test_case_name(), testinfo->name());
                            }
                        }
                    }
                }
            }
        }
        {
            const int count = test.reportable_test_run_skipped_count();
            if( count > 0 )
            {
                detail::iuConsole::color_output(detail::iuConsole::yellow, "[  SKIPPED ] ");
                detail::iuConsole::output("%d tests.\n", count );
                if( TestFlag::IsEnableFlag(TestFlag::VERBOSE) )
                {
                    for( int i=0, case_count=test.total_test_case_count(); i < case_count; ++i )
                    {
                        const TestCase* testcase = test.GetTestCase(i);
                        for( int j=0, info_count=testcase->total_test_count(); j < info_count; ++j )
                        {
                            const TestInfo* testinfo = testcase->GetTestInfo(j);
                            if( testinfo->is_skipped() )
                            {
                                detail::iuConsole::color_output(detail::iuConsole::yellow, "[  SKIPPED ] ");
                                detail::iuConsole::output("%s.%s\n", testinfo->test_case_name(), testinfo->name());
                            }
                        }
                    }
                }
            }
        }

        if( !test.Passed() )
        {
            const int failed_num = test.failed_test_count();
            detail::iuConsole::color_output(detail::iuConsole::red, "[  FAILED  ] ");
            detail::iuConsole::output("%d %s, listed below:\n", failed_num, failed_num == 1 ? "test" : "tests" );

            for( int i=0, count=test.total_test_case_count(); i < count; ++i )
            {
                const TestCase* testcase = test.GetTestCase(i);
                for( int j=0, info_count=testcase->total_test_count(); j < info_count; ++j )
                {
                    const TestInfo* testinfo = testcase->GetTestInfo(j);
                    if( testinfo->HasFailure() )
                    {
                        detail::iuConsole::color_output(detail::iuConsole::red, "[  FAILED  ] ");
                        detail::iuConsole::output("%s.%s\n", testinfo->test_case_name(), testinfo->name());
                    }
                }
                if( testcase->ad_hoc_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 DefaultResultPrintListener::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_stderr_xml_generator.hpp
 * @brief       output stderr (junit) xml event listener
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STDERR_XML_GENERATOR_HPP_44748A14_3446_49D5_8ECE_05ABED0FFF33_
#define INCG_IRIS_IUTEST_STDERR_XML_GENERATOR_HPP_44748A14_3446_49D5_8ECE_05ABED0FFF33_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_junit_xml_generator.hpp
 * @brief       output junit xml event listener
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2014-2016, 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-2016, 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_format;
    ::std::string m_output_path;
protected:
    IFile* m_fp;
public:
    /**
     * @brief   コンストラクタ
     * @param [in] path = 出力パス
    */
    explicit DefaultXmlGeneratorListener(const ::std::string& path)
        : m_fp(NULL)
    {
        SetFilePath(path);
    }
    virtual ~DefaultXmlGeneratorListener()
    {
        FileClose();
        TestEnv::event_listeners().set_default_xml_generator(NULL);
    }
public:
    /**
     * @brief   出力ファイルパスの取得
    */
    const ::std::string& GetFilePath() const { return m_output_path; }

private:
    /**
     * @brief   出力ファイルの設定
    */
    void SetFilePath(const ::std::string& path)
    {
        if( path.empty() )
        {
            m_output_path_format.clear();
            m_output_path = detail::kStrings::DefaultXmlReportFileName;
        }
        else
        {
            m_output_path_format = path;
            const ::std::string::size_type pos = path.find('.');
            if( pos == ::std::string::npos
                || pos == path.length()-1 )
            {
                m_output_path_format += detail::GetPathSeparator();
                m_output_path_format += detail::kStrings::DefaultXmlReportFileName;
            }
            m_output_path = m_output_path_format;
        }
    }

public:
    virtual void OnTestIterationStart(const UnitTest& test, int iteration) 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:
    virtual bool FileOpen(const char* path);
    virtual void FileClose();

protected:
    static void OutputXmlCDataSection(IFile* file, const char* data);
    static void OutputXmlAttribute(IFile* file, const char* name, const char* value);

protected:
    static ::std::string EscapeXmlAttribute(const char* str)
    {
        return EscapeXml(str, true);
    }
    static ::std::string EscapeXmlAttribute(const ::std::string str)
    {
        return EscapeXml(str.c_str(), true);
    }
    static ::std::string EscapeXmlText(const char* str)
    {
        return EscapeXml(str, false);
    }
    /**
     * @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 bool SetUp()
    {
        ::std::string xmlpath = TestEnv::get_report_xml_filepath();
        if( !xmlpath.empty() )
        {
            TestEnv::event_listeners().set_default_xml_generator(new DefaultXmlGeneratorListener(xmlpath));
            return true;
        }
        return false;
    }
};

}   // 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-2016, 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::OnTestIterationStart(const UnitTest& test, int iteration)
{
    IUTEST_UNUSED_VAR(test);
    if( !m_output_path_format.empty() )
    {
        m_output_path = detail::StringFormat(m_output_path_format.c_str(), iteration);
        if( m_output_path == m_output_path_format)
        {
            m_output_path_format.clear();
        }
        if( m_fp != NULL )
        {
            OnReportTest(m_fp, test);
            FileClose();
        }
    }
    if( m_fp == NULL )
    {
        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() )
        {
            ::std::string message = detail::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number());
#if 0
            OutputXmlAttribute(file, "message"
                , EscapeXmlAttribute(part.summary()).c_str());
            file->Printf(">\n");
            message += "\n";
            message += detail::MultiByteStringToUTF8(part.summary());
            OutputXmlCDataSection(file, message.c_str());
            file->Printf("\n      </skipped>\n");
#else
            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()
{
    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];
                            detail::iu_snprintf(tmp, sizeof(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 = 出力パス
    */
    explicit JunitXmlGeneratorListener(const ::std::string& path)
        : DefaultXmlGeneratorListener(path)
    {
    }
    virtual ~JunitXmlGeneratorListener()
    {
    }
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 bool SetUp()
    {
        ::std::string xmlpath = TestEnv::get_report_junit_xml_filepath();
        if( !xmlpath.empty() )
        {
            TestEnv::event_listeners().set_default_xml_generator(new JunitXmlGeneratorListener(xmlpath));
            return true;
        }
        return false;
    }
};

}   // 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-2016, 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());

    const bool notrun = test_info.should_run() && !test_info.is_ran();
    if( test_info.HasFailure() || notrun )
    {
        for( int i=0, count=test_info.result()->total_part_count(); i < count; ++i )
        {
            const TestPartResult& part = test_info.result()->GetTestPartResult(i);
            if( part.passed() )
            {
                continue;
            }

            file->Printf("      <failure ");
            OutputXmlAttribute(file, "message"
                , EscapeXmlAttribute(part.summary()).c_str());
            file->Printf("type=\"\">");
            ::std::string message = detail::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number());
            message += "\n";
            message += detail::MultiByteStringToUTF8(part.summary());
            OutputXmlCDataSection(file, message.c_str());
            file->Printf("\n      </failure>\n");
        }
        if( notrun )
        {
            file->Printf("      <failure message=\"Not Run\" type=\"\">");
            OutputXmlCDataSection(file, "Not Run");
            file->Printf("\n      </failure>\n");
        }
    }
    else
    {
        const bool skipped = test_info.is_skipped() || !test_info.should_run();
        if( skipped )
        {
            OnReportTestSkipped(file, test_info);
        }
    }
    file->Printf("    </testcase>\n");
}


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_

namespace iutest
{

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

namespace detail
{

/**
 * @brief   xml result output to stderr
*/
template<typename T, typename ::std::string (*GetXmlPath)()>
class StderrXmlGeneratorListenerBase : public T
{
public:
    /**
     * @brief   コンストラクタ
     * @param [in] path = 出力パス
    */
    explicit StderrXmlGeneratorListenerBase(const ::std::string& path) : T(path) {}

    ~StderrXmlGeneratorListenerBase() {}

#if IUTEST_HAS_FOPEN
private:
    StdErrorFile m_stderr;

    virtual bool FileOpen(const char* path)
    {
        if( m_stderr.Open(path, IFile::OpenReadWrite) )
        {
            this->m_fp = &m_stderr;
            return true;
        }
        return false;
    }
    virtual void FileClose()
    {
        this->m_fp = NULL;
    }
#endif

public:
    
    static bool SetUp()
    {
        ::std::string xmlpath = GetXmlPath();
        if( !xmlpath.empty() )
        {
            TestEnv::event_listeners().set_default_xml_generator(new StderrXmlGeneratorListenerBase(xmlpath));
            return true;
        }
        return false;
    }
};

}   // end of namespace detail

typedef detail::StderrXmlGeneratorListenerBase<
    DefaultXmlGeneratorListener, TestEnv::get_report_xml_filepath> StderrXmlGeneratorListener;
typedef detail::StderrXmlGeneratorListenerBase<
    JunitXmlGeneratorListener, TestEnv::get_report_junit_xml_filepath> StderrJunitXmlGeneratorListener;

}   // end of namespace iutest

#endif // INCG_IRIS_IUTEST_STDERR_XML_GENERATOR_HPP_44748A14_3446_49D5_8ECE_05ABED0FFF33_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_streaming_listener.hpp
 * @brief       iris unit test stream result
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STREAMING_LISTENER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_
#define INCG_IRIS_IUTEST_STREAMING_LISTENER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_

//======================================================================
// include
#if IUTEST_HAS_STREAM_RESULT
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_socket.hpp
 * @brief       soket
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2016, 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;
    typedef int length_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;
    typedef size_t length_t;

#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
    static const descriptor_t INVALID_DESCRIPTOR = -1;
#else
    enum { INVALID_DESCRIPTOR = -1 };
#endif

#endif
public:
    BasicSocket() : 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, static_cast<length_t>(curr->ai_addrlen)) != -1 )
                {
                    m_socket = fd;
                    break;
                }
                Close(fd);
            }
        }
        freeaddrinfo(servinfo);
        return (m_socket != INVALID_DESCRIPTOR);
    }
    void Close()
    {
        Close(m_socket);
        m_socket = INVALID_DESCRIPTOR;
    };
    void CheckLastError()
    {
#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() 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() {}
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() {}
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() {}
};

}   // 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()
    {
        ::std::string addr = TestEnv::get_stream_result_to();
        if( addr.empty() )
        {
            return NULL;
        }
        const size_t pos = addr.find(':');
        if( pos == ::std::string::npos )
        {
            return NULL;
        }
        TestEventListener* p = new StreamResultListener(addr.substr(0, pos).c_str(), addr.substr(pos+1).c_str());
        UnitTest::GetInstance()->listeners().Append(p);
        return p;
    }
};

}   // 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-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STREAMING_LISTENER_IPP_1187A63F_E99B_4289_A562_3C87B9739B7D_
#define INCG_IRIS_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&passed=" + 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-2016, 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
{

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

/**
 * @brief mfc map container iterator
*/
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 base_type<T>::BASE_TYPE BASE_TYPE;
    typedef typename base_type<T>::BASE_KEY BASE_KEY;
    typedef typename 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;
};

}   // end of namespace peep

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 peep::mfc_iterator_traits<T>::type begin(T& map
    , typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetStartPosition), void>::type*& = detail::enabler::value)
{
    return typename peep::mfc_iterator_traits<T>::type(map, map.GetStartPosition());
}
template<typename T>
typename peep::mfc_iterator_traits<T>::type end(T& map
    , typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetStartPosition), void>::type*& = detail::enabler::value)
{
    return typename peep::mfc_iterator_traits<T>::type(map, NULL);
}

/**
 * @brief   provide begin/end in mfc container
*/
template<typename T>
class CContainer
{
public:
    /**
     * @private
     * @{
    */
    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 peep::mfc_iterator_traits<T>::type iterator_type;
    /**
     * @}
    */
public:
    explicit 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;
};

/** 
 * @brief   make mfc 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   testcasename_   = テストケース名
 * @param   testfixture_    = テストフィクスチャ名
*/
#define IUTEST_ALIAS_TESTNAME_F(testcasename_, testfixture_)    IUTEST_ALIAS_TESTNAME_F_(testcasename_, testfixture_)

#if IUTEST_HAS_TESTNAME_ALIAS_JP

/**
 * @ingroup TESTDEF
 * @brief   日本語テスト名
 * @param   testname_       = テスト名
*/
#define IUTEST_JAPANESE_NAME(testname_)                         IUTEST_ALIAS_TESTNAME(testname_)

/**
 * @ingroup TESTDEF
 * @brief   テストフィクスチャ用日本語テスト名
 * @param   testcasename_   = テストケース名
 * @param   testfixture_    = テストフィクスチャ名
*/
#define IUTEST_JAPANESE_NAME_F(testcasename_, testfixture_)     IUTEST_ALIAS_TESTNAME_F(testcasename_, testfixture_)

#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() { static UnitTestSource inst; return inst; }

private:
    UnitTestSource()
    {
#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 DefaultResultPrintListener());
    }

public:
    
    ~UnitTestSource()
    {
        TestEnv::event_listeners().set_default_result_printer(NULL);
        TestEnv::event_listeners().set_default_xml_generator(NULL);
    }

public:
    /**
     * @brief   初期化
    */
    void Initialize()
    {
        UnitTest::instance().Initialize();
    }

    /**
     * @brief   テストの実行
    */
    int Run()
    {
        SetUpDefaultListener();
        return UnitTest::instance().Run();
    }

private:
    void SetUpDefaultListener()
    {
        if( TestEnv::has_output_option() )
        {
            do
            {
#if defined(__WANDBOX__)
                if( StderrXmlGeneratorListener::SetUp() )
                {
                    break;
                }
                if( StderrJunitXmlGeneratorListener::SetUp() )
                {
                    break;
                }
#else
                if( DefaultXmlGeneratorListener::SetUp() )
                {
                    break;
                }
                if( JunitXmlGeneratorListener::SetUp() )
                {
                    break;
                }
#endif
                IUTEST_LOG_(WARNING) << "unrecognized output format \"" << TestEnv::get_output_option() << "\" ignored.";
            } while( detail::AlwaysFalse() );
        }

#if IUTEST_HAS_STREAM_RESULT
        StreamResultListener::SetUp();
#endif
    }
};

//======================================================================
// 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();
}

}   // end of namespace detail

/**
 * @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() { 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);
}

}   // end of namespace iutest

#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-2017, 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_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_switch_for_gtest.hpp
 * @brief       switching to iutest from gtest / gtest from iutest
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_FOR_GTEST_HPP_5770CDF3_B5D0_46BC_AAF8_B721902F9871
#define INCG_IRIS_IUTEST_SWITCH_FOR_GTEST_HPP_5770CDF3_B5D0_46BC_AAF8_B721902F9871

#if 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 <string.h>
#  include <stdlib.h>
#  include <cstdio>
#  define __STRICT_ANSI__
#endif

//======================================================================
// include
#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-2016, 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-2017, 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

//!< Micro Version
#ifndef GTEST_MICROVER
#  if GTEST_MINORVER == 0x02 && defined(GTEST_HAS_CLONE)
#    define GTEST_MICROVER  0x01
#  elif GTEST_MINORVER == 0x00
// 判断難しい
#    define GTEST_MICROVER  0x01
#  else
#    define GTEST_MICROVER  0x00
#  endif
#endif

#ifndef GTEST_BUILD
#  define GTEST_BUILD       GTEST_MICROVER  //!< @deprecated
#endif

#ifndef GTEST_REVISION
#  define GTEST_REVISION    0x00        //!< Revision
#endif

#ifndef GTEST_VER
#  define   GTEST_VER       ((GTEST_MAJORVER<<24)   \
                            |(GTEST_MINORVER<<16)   \
                            |(GTEST_MICROVER<< 8)   \
                            |(GTEST_REVISION<< 0)   \
                            )   //!< google test version
#endif

#endif

#endif // INCG_IRIS_IUTEST_GTEST_VER_HPP_7396AEF4_D1AB_44B5_9FE3_23CEC1240158_

//======================================================================
// 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_PAIRWISE
#undef IUTEST_HAS_CONCAT
#undef IUTEST_HAS_CSVPARAMS
#undef IUTEST_HAS_VARIADIC_VALUES
#undef IUTEST_HAS_VARIADIC_COMBINE
#undef IUTEST_HAS_VARIADIC_PAIRWISE
#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_TYPED_TEST_APPEND_TYPENAME
#undef IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR

#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_CATCH_SEH_EXCEPTION_ASSERTION
#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_STREAM_BUFFER

#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_PAIRWISE                 0
#define IUTEST_HAS_CONCAT                   0
#define IUTEST_HAS_CSVPARAMS                0
#define IUTEST_HAS_VARIADIC_VALUES          0
#define IUTEST_HAS_VARIADIC_COMBINE         0
#define IUTEST_HAS_VARIADIC_PAIRWISE        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_TYPED_TEST_APPEND_TYPENAME   0
#if GTEST_VER < 0x01080000
#  define IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR    0
#else
#  define IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR    1
#endif

#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_CATCH_SEH_EXCEPTION_ASSERTION    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_STREAM_BUFFER        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_CXX_OVERRIDE
#  define IUTEST_CXX_OVERRIDE
#endif
#ifndef IUTEST_CXX_DEFAULT_FUNCTION
#  define IUTEST_CXX_DEFAULT_FUNCTION   {}
#endif

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_switch_port.hpp
 * @brief       portable 定義切り替え ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2016, 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
#if defined(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_NO_PUTENV) || defined(__STRICT_ANSI__) \
    || defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE)
    (void)(expr);
    return -1;
#elif defined(IUTEST_OS_WINDOWS)
    return _putenv(expr);
#else
    return putenv(const_cast<char*>(expr));
#endif
}

inline int SetEnv(const char* name, const char* value, int overwrite)
{
#if defined(IUTEST_NO_SETENV) || defined(__STRICT_ANSI__) \
    || defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE)
    (void)(name);
    (void)(value);
    (void)(overwrite);
    return -1;
#elif defined(IUTEST_OS_WINDOWS)
    if( overwrite == 0 )
    {
        if( GetEnv(name) != NULL )
        {
            return 0;
        }
    }
    ::std::string expr = name;
    expr += "=";
    expr += value;
    return PutEnv(expr.c_str());
#else
    return setenv(name, value, overwrite);
#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-2016, 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
#if defined(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_FRIEND_TYPED_TEST_P_DECLARATION
#undef IUTEST_FRIEND_TYPED_TEST_P
#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_FRIEND_TYPED_TEST_P_DECLARATION(test_case_name, test_name)   \
    namespace GTEST_CASE_NAMESPACE_(test_case_name) { template<typename T>class test_name; }
#define IUTEST_FRIEND_TYPED_TEST_P(test_case_name, test_name)               \
   template<typename T>friend class GTEST_CASE_NAMESPACE_(test_case_name)::test_name
#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-2016, 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 matchers
}   // 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-2016, 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-2016, 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
#if defined(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
#if defined(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-2016, 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
#if defined(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()
{
    // INFORM 用に printer を追加
    ::testing::UnitTest::GetInstance()->listeners().Append( new DefaultPrinter() );
}

}   // end of namespace inform_support
}   // end of namespace testing

#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-2016, 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-2016, 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
#if defined(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() {}
    AssertionReturnType(const T& v) : value(v) {}   // NOLINT
};
template<>
struct AssertionReturnType<void>
{
    AssertionReturnType() {}
};

template<typename T>
inline AssertionReturnType<T> AssertionReturn(const T& ret) { return AssertionReturnType<T>(ret); }
inline AssertionReturnType<void> AssertionReturn() { 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-2016, 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-2016, 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-2016, 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-2016, 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-2016, 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-2016, 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-2016, 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
#if defined(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() : m_has_new_failure(false)
    {
    }
    virtual ~HasNewFailureHelper()
    {
    }
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-2016, 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-2016, 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_

#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__)    // NOLINT
#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
}   // end of namespace tuples

#if GTEST_VER < 0x01080000
using tuples::tuple;
using tuples::tuple_size;
using tuples::tuple_element;
#endif

using tuples::make_tuple;
using tuples::get;

#if !defined(IUTEST_USING_BEGIN_END)
#  define IUTEST_USING_BEGIN_END()  \
    using ::std::begin; using ::std::end
#endif

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-2016, 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-2016, 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, actual, on_failure)  IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexEq, regex, actual, on_failure )
#define IUTEST_TEST_MATCHES_REGEXNE(regex, actual, on_failure)  IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexNe, regex, actual, on_failure )

#define IUTEST_TEST_CONTAINS_REGEXEQ(regex, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexEq, regex, actual, on_failure )
#define IUTEST_TEST_CONTAINS_REGEXNE(regex, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexNe, regex, 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) )
    {
        return ::iutest::AssertionSuccess();
    }
    else
    {
        return ::iutest::AssertionFailure() << "error: Expected: { " << expr1b << ", " << expr1e << " } == { "
            << expr2b << ", " << expr2e << " }\n  Actual:" << ar.message();
    }
}

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) )
    {
        return ::iutest::AssertionSuccess();
    }
    else
    {
        return ::iutest::AssertionFailure() << "error: Expected: " << expected_expr << " == " << actual_expr
            << " \n  Actual:" << ar.message();
    }
}

}   // end of namespace detail

/**
 * @brief   Equal Range Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const T1& expected, const 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
    , const 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], const T2& actual)
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
        , actual.begin(), actual.end());
}
#if IUTEST_HAS_INITIALIZER_LIST


template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const ::std::initializer_list<T1>& expected, const T2& actual)
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
        , actual.begin(), actual.end());
}

template<typename T1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const ::std::initializer_list<T1>& expected, T2(&actual)[SIZE2])
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
        , actual, actual + SIZE2);
}

#endif

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

}   // end of namespace StrInHelper

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

}   // end of namespace StrNotInHelper

/**
 * @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, const ::iutest::internal::RE& re)
{
    return ::iutest::internal::RE::FullMatch(str, re);
}
inline bool FullMatch(const char* str, const ::iutest::internal::RE& re)
{
    if( str == NULL )
    {
        return false;
    }
    return ::iutest::internal::RE::FullMatch(str, re);
}

inline bool PartialMatch(const ::std::string& str, const ::iutest::internal::RE& re)
{
    return ::iutest::internal::RE::PartialMatch(str, re);
}
inline bool PartialMatch(const char* str, const ::iutest::internal::RE& re)
{
    if( str == NULL )
    {
        return false;
    }
    return ::iutest::internal::RE::PartialMatch(str, re);
}

}   // end of namespace RegexHelper

namespace MatchesRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex, const T2& actual)
{
    ::iutest::internal::RE iure(regex);
    return RegexHelper::FullMatch(actual, iure);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult 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);
}

}   // end of namespace MatchesRegexEqHelper

/**
 * @brief   文字列正規表現一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexEq(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return MatchesRegexEqHelper::Assertion(regex_str, actual_str, regex, 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);
}

}   // end of namespace MatchesRegexNeHelper

/**
 * @brief   文字列正規表現不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexNe(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return MatchesRegexNeHelper::Assertion(regex_str, actual_str, regex, actual);
}

namespace ContainsRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex, const T2& actual)
{
    ::iutest::internal::RE m(regex);
    return RegexHelper::PartialMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult 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);
}

}   // end of namespace ContainsRegexEqHelper

/**
 * @brief   文字列正規表現部分一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexEq(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return ContainsRegexEqHelper::Assertion(regex_str, actual_str, regex, 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);
}

}   // end of namespace ContainsRegexNeHelper

/**
 * @brief   文字列正規表現部分不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexNe(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return ContainsRegexNeHelper::Assertion(regex_str, actual_str, regex, 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-2016, 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
#if defined(INCG_IRIS_IUTEST_SWITCH_HPP_)
#  if defined(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-2016, 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_

namespace iuutil
{

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

/**
 * @brief   コンパクトなデフォルトコンソール出力イベントリスナー
*/
class QuietResultPrinter : public ::iutest::TestEventListener
{
public:
    explicit QuietResultPrinter(::iutest::TestEventListener* default_printer)
        : m_default_printer(default_printer)
    {}
    virtual ~QuietResultPrinter()
    {
        delete m_default_printer;
    }

public:
    virtual void OnTestProgramStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestProgramStart(unit_test);
    }
    virtual void OnTestIterationStart(const ::iutest::UnitTest& unit_test, int iteration) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestIterationStart(unit_test, iteration);
    }
    virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsSetUpStart(unit_test);
    }
    virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsSetUpEnd(unit_test);
    }
    virtual void OnTestCaseStart(const ::iutest::TestCase& test_case) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestCaseStart(test_case);
    }

#if 0
    virtual void OnTestStart(const ::iutest::TestInfo& test_info) IUTEST_CXX_OVERRIDE {}

    virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE
    {
        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) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestStart(test_info);
    }
    virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestPartResult(test_part_result);
    }
#endif

    virtual void OnTestEnd(const ::iutest::TestInfo& test_info) IUTEST_CXX_OVERRIDE
    {
        if( test_info.result()->Failed() )
        {
            // 失敗したときのみ出力する
            m_default_printer->OnTestEnd(test_info);
        }
    }
    virtual void OnTestCaseEnd(const ::iutest::TestCase& test_case) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestCaseEnd(test_case);
    }
    virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsTearDownStart(unit_test);
    }
    virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsTearDownEnd(unit_test);
    }
    virtual void OnTestIterationEnd(const ::iutest::UnitTest& unit_test, int iteration) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestIterationEnd(unit_test, iteration);
    }
    virtual void OnTestProgramEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestProgramEnd(unit_test);
    }
private:
    ::iutest::TestEventListener* m_default_printer;

public:
    /**
     * @brief   QuietResultPrinter に切り替え
    */
    static ::iutest::TestEventListener* SetUp()
    {
        ::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-2016, 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_

#if defined(MS_CPP_UNITTESTFRAMEWORK)
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_util_vc_unittest.hpp
 * @brief       iris unit test, visual studio 11 C++ Unit Test Framework 対応 ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2015-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_
#define INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_

//======================================================================
// include
#include "CppUnitTest.h"

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

#ifdef IUTEST_USE_GTEST

#ifdef IIUT_TEST_P_
#  undef IIUT_TEST_P_
#endif
#define IIUT_TEST_P_    TEST_P

#ifdef IIUT_TYPED_TEST_
#  undef IIUT_TYPED_TEST_
#endif
#define IIUT_TYPED_TEST_    TYPED_TEST

#ifdef IIUT_TYPED_TEST_P_
#  undef IIUT_TYPED_TEST_P_
#endif
#define IIUT_TYPED_TEST_P_  TYPED_TEST_P

#endif

/**
 * @private
 * @{
*/

#ifdef IUTEST
#  undef IUTEST
#endif
#define IUTEST(testcase_, testname_)    \
    IUTEST_VCUNIT_I(testcase_, testname_, testcase_##testname_##_class, testcase_##_##testname_);   \
    IUTEST_TEST(testcase_, testname_)

#ifdef IUTEST_F
#  undef IUTEST_F
#endif
#define IUTEST_F(testfixture_, testname_)   \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TEST_F_(testfixture_, testname_)

#ifdef IUTEST_P
#  undef IUTEST_P
#endif
#define IUTEST_P(testfixture_, testname_)   \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TEST_P_(testfixture_, testname_)

#ifdef IUTEST_TYPED_TEST
#  undef IUTEST_TYPED_TEST
#endif
#define IUTEST_TYPED_TEST(testfixture_, testname_)  \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TYPED_TEST_(testfixture_, testname_)

#ifdef IUTEST_TYPED_TEST_P
#  undef IUTEST_TYPED_TEST_P
#endif
#define IUTEST_TYPED_TEST_P(testfixture_, testname_)    \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IIUT_TYPED_TEST_P_(testfixture_, testname_)


#define IUTEST_VCUNIT_I(testcase_, testname_, className, methodName)    \
    IUTEST_VCUNIT_TEST_CLASS(className) {                               \
    public: TEST_METHOD(methodName) {                                   \
        IUTEST_VCUNIT_EXEC_(testcase_, testname_); }                    \
    IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)                 \
    }

//#define IUTEST_VCUNIT_F(testcase_, testname_, className, methodName)  \
//  IUTEST_VCUNIT_TEST_CLASS(className) {                               \
//  public: TEST_METHOD(methodName) {                                   \
//      IUTEST_VCUNIT_EXEC_(testcase_, testname_); }                    \
//  IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)                 \
//  TEST_CLASS_INITIALIZE(iuSetUp) { testcase_::SetUpTestCase(); }      \
//  TEST_CLASS_CLEANUP(iuTearDown) { testcase_::TearDownTestCase(); }   \
//  }

#define IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)     \
    BEGIN_TEST_METHOD_ATTRIBUTE(methodName)                     \
        TEST_METHOD_ATTRIBUTE(L"TestCase", L#testcase_)         \
    END_TEST_METHOD_ATTRIBUTE()

#define IUTEST_VCUNIT_EXEC_(testcase_, testname_)   \
    Body( "*" #testcase_ "." #testname_ "*" )

#define IUTEST_VCUNIT_TEST_CLASS(className) \
    ONLY_USED_AT_NAMESPACE_SCOPE class className : public ::iuutil::VisualStudio::TestClass<className>

//======================================================================
// class
namespace iuutil {
namespace VisualStudio
{

template<typename T>
class TestClass : public ::Microsoft::VisualStudio::CppUnitTestFramework::TestClass<T>
{
    typedef ::Microsoft::VisualStudio::CppUnitTestFramework::Logger Logger;
public:
    void Body(const char* filter)
    {
        SetUpCppUnitTest();
        ::iutest::IUTEST_FLAG(catch_exceptions) = false;
        ::iutest::IUTEST_FLAG(filter) = filter;
        ::iutest::IUTEST_FLAG(also_run_disabled_tests) = true;
        IUTEST_RUN_ALL_TESTS();
    }
};

/**
 * @brief   Logger
*/
class VCCppUnitTestLogger : public ::iutest::detail::iuLogger
{
    typedef ::Microsoft::VisualStudio::CppUnitTestFramework::Logger Logger;
public:
    virtual void voutput(const char* fmt, va_list va)
    {
        int length = _vscprintf(fmt, va);
        if( length <= 0 )
        {
            return;
        }
        length += 1;
        char* buf = new char [length];
        vsprintf_s(buf, length, fmt, va);
        m_log += buf;
        delete [] buf;

        int pos = m_log.find('\n');
        while(pos >= 0) {
            Logger::WriteMessage(m_log.substr(0, pos).c_str());
            m_log = m_log.substr(pos+1);
            pos = m_log.find('\n');
        }
    }
private:
    ::std::string m_log;
};

/**
 * @brief   Hook 用リポーター
*/
class VCCppUnitTestPartResultReporter : public ::iutest::EmptyTestEventListener
{
public:
    VCCppUnitTestPartResultReporter()
    {
        ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
        listeners.Append(this);
    }
    virtual ~VCCppUnitTestPartResultReporter()
    {
        ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
        listeners.Release(this);
    }
    virtual void OnTestPartResult(const ::iutest::TestPartResult& result)
    {
        // VC にも送る
        if( result.failed() )
        {
            size_t size=0;
            wchar_t buf1[4096]; // TODO: Fixed buffer...
            wchar_t buf2[MAX_PATH];
            ::mbstowcs_s(&size, buf1, sizeof(buf1)/sizeof(buf1[0]), result.message(), _TRUNCATE);
            ::mbstowcs_s(&size, buf2, sizeof(buf2)/sizeof(buf2[0]), result.file_name(), _TRUNCATE);
            ::Microsoft::VisualStudio::CppUnitTestFramework::Assert::Fail(buf1
                , &Microsoft::VisualStudio::CppUnitTestFramework::__LineInfo(buf2, "", result.line_number()) );
        }
    }
};

class VCCppUnitResultPrinter : public ::iutest::TestEventListener
{
public:
    explicit VCCppUnitResultPrinter(::iutest::TestEventListener* default_printer)
        : m_default_printer(default_printer)
    {}
    virtual ~VCCppUnitResultPrinter()
    {
        delete m_default_printer;
    }

public:
    virtual void OnTestProgramStart(const ::iutest::UnitTest& ) {}

    virtual void OnTestIterationStart(const ::iutest::UnitTest& , int ) {}

    virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& ) {}

    virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& ) {}

    virtual void OnTestCaseStart(const ::iutest::TestCase& ) {}

    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);
    }
    virtual void OnTestEnd(const ::iutest::TestInfo& test_info)
    {
        m_default_printer->OnTestEnd(test_info);
    }

    virtual void OnTestCaseEnd(const ::iutest::TestCase& ) {}

    virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& ) {}

    virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& ) {}

    virtual void OnTestIterationEnd(const ::iutest::UnitTest& , int iteration) {}

    virtual void OnTestProgramEnd(const ::iutest::UnitTest& ) {}
private:
    ::iutest::TestEventListener* m_default_printer;

public:
    /**
    * @brief    VCCppUnitResultPrinter に切り替え
    */
    static ::iutest::TestEventListener* SetUp()
    {
        static ::iutest::TestEventListener* p = NULL;
        if( p == NULL )
        {
            ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
            ::iutest::TestEventListener* default_printer = listeners.Release(listeners.default_result_printer());
            if( default_printer == NULL )
            {
                return NULL;
            }
            p = new VCCppUnitResultPrinter(default_printer);
            listeners.Append(p);
        }
        return p;
    }
};

inline void SetUpCppUnitTest()
{
    {
        static VCCppUnitTestPartResultReporter fake;
#ifndef IUTEST_USE_GTEST
        static VCCppUnitTestLogger logger;
        ::iutest::detail::iuConsole::SetLogger(&logger);
        ::iutest::UnitTestSource::GetInstance().Initialize();
#endif
        VCCppUnitResultPrinter::SetUp();
    }
}

}   // end of namespace VisualStudio
}   // end of namespace iuutil

/**
 * @}
*/


#endif  // INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_
#endif

/**
 * @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_FOR_GTEST_HPP_5770CDF3_B5D0_46BC_AAF8_B721902F9871
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_switch_for_iutest.hpp
 * @brief       switching to iutest from gtest / gtest from iutest
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2011-2017, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_FOR_IUTEST_HPP_478A7B61_F2AE_480D_AF26_1AC5162F7B13
#define INCG_IRIS_IUTEST_SWITCH_FOR_IUTEST_HPP_478A7B61_F2AE_480D_AF26_1AC5162F7B13

#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

#undef GTEST_IS_THREADSAFE

#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

#define GTEST_IS_THREADSAFE     0







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

}   // end of namespace iutest

#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

#endif

#endif // INCG_IRIS_IUTEST_SWITCH_FOR_IUTEST_HPP_478A7B61_F2AE_480D_AF26_1AC5162F7B13

#endif // INCG_IRIS_IUTEST_SWITCH_HPP_
#endif

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_util.hpp
 * @brief       iris unit test utility
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2012-2016, 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-2016, 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, actual, on_failure)  IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexEq, regex, actual, on_failure )
#define IUTEST_TEST_MATCHES_REGEXNE(regex, actual, on_failure)  IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexNe, regex, actual, on_failure )

#define IUTEST_TEST_CONTAINS_REGEXEQ(regex, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexEq, regex, actual, on_failure )
#define IUTEST_TEST_CONTAINS_REGEXNE(regex, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexNe, regex, 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) )
    {
        return ::iutest::AssertionSuccess();
    }
    else
    {
        return ::iutest::AssertionFailure() << "error: Expected: { " << expr1b << ", " << expr1e << " } == { "
            << expr2b << ", " << expr2e << " }\n  Actual:" << ar.message();
    }
}

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) )
    {
        return ::iutest::AssertionSuccess();
    }
    else
    {
        return ::iutest::AssertionFailure() << "error: Expected: " << expected_expr << " == " << actual_expr
            << " \n  Actual:" << ar.message();
    }
}

}   // end of namespace detail

/**
 * @brief   Equal Range Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const T1& expected, const 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
    , const 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], const T2& actual)
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
        , actual.begin(), actual.end());
}
#if IUTEST_HAS_INITIALIZER_LIST


template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const ::std::initializer_list<T1>& expected, const T2& actual)
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
        , actual.begin(), actual.end());
}

template<typename T1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
    , const ::std::initializer_list<T1>& expected, T2(&actual)[SIZE2])
{
    return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
        , actual, actual + SIZE2);
}

#endif

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

}   // end of namespace StrInHelper

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

}   // end of namespace StrNotInHelper

/**
 * @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, const ::iutest::internal::RE& re)
{
    return ::iutest::internal::RE::FullMatch(str, re);
}
inline bool FullMatch(const char* str, const ::iutest::internal::RE& re)
{
    if( str == NULL )
    {
        return false;
    }
    return ::iutest::internal::RE::FullMatch(str, re);
}

inline bool PartialMatch(const ::std::string& str, const ::iutest::internal::RE& re)
{
    return ::iutest::internal::RE::PartialMatch(str, re);
}
inline bool PartialMatch(const char* str, const ::iutest::internal::RE& re)
{
    if( str == NULL )
    {
        return false;
    }
    return ::iutest::internal::RE::PartialMatch(str, re);
}

}   // end of namespace RegexHelper

namespace MatchesRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex, const T2& actual)
{
    ::iutest::internal::RE iure(regex);
    return RegexHelper::FullMatch(actual, iure);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult 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);
}

}   // end of namespace MatchesRegexEqHelper

/**
 * @brief   文字列正規表現一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexEq(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return MatchesRegexEqHelper::Assertion(regex_str, actual_str, regex, 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);
}

}   // end of namespace MatchesRegexNeHelper

/**
 * @brief   文字列正規表現不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexNe(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return MatchesRegexNeHelper::Assertion(regex_str, actual_str, regex, actual);
}

namespace ContainsRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex, const T2& actual)
{
    ::iutest::internal::RE m(regex);
    return RegexHelper::PartialMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult 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);
}

}   // end of namespace ContainsRegexEqHelper

/**
 * @brief   文字列正規表現部分一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexEq(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return ContainsRegexEqHelper::Assertion(regex_str, actual_str, regex, 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);
}

}   // end of namespace ContainsRegexNeHelper

/**
 * @brief   文字列正規表現部分不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexNe(const char* regex_str, const char* actual_str
    , const char* regex, const char* actual)
{
    return ContainsRegexNeHelper::Assertion(regex_str, actual_str, regex, 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-2016, 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
#if defined(INCG_IRIS_IUTEST_SWITCH_HPP_)
#  if defined(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-2016, 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_

namespace iuutil
{

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

/**
 * @brief   コンパクトなデフォルトコンソール出力イベントリスナー
*/
class QuietResultPrinter : public ::iutest::TestEventListener
{
public:
    explicit QuietResultPrinter(::iutest::TestEventListener* default_printer)
        : m_default_printer(default_printer)
    {}
    virtual ~QuietResultPrinter()
    {
        delete m_default_printer;
    }

public:
    virtual void OnTestProgramStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestProgramStart(unit_test);
    }
    virtual void OnTestIterationStart(const ::iutest::UnitTest& unit_test, int iteration) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestIterationStart(unit_test, iteration);
    }
    virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsSetUpStart(unit_test);
    }
    virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsSetUpEnd(unit_test);
    }
    virtual void OnTestCaseStart(const ::iutest::TestCase& test_case) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestCaseStart(test_case);
    }

#if 0
    virtual void OnTestStart(const ::iutest::TestInfo& test_info) IUTEST_CXX_OVERRIDE {}

    virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE
    {
        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) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestStart(test_info);
    }
    virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestPartResult(test_part_result);
    }
#endif

    virtual void OnTestEnd(const ::iutest::TestInfo& test_info) IUTEST_CXX_OVERRIDE
    {
        if( test_info.result()->Failed() )
        {
            // 失敗したときのみ出力する
            m_default_printer->OnTestEnd(test_info);
        }
    }
    virtual void OnTestCaseEnd(const ::iutest::TestCase& test_case) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestCaseEnd(test_case);
    }
    virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsTearDownStart(unit_test);
    }
    virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnEnvironmentsTearDownEnd(unit_test);
    }
    virtual void OnTestIterationEnd(const ::iutest::UnitTest& unit_test, int iteration) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestIterationEnd(unit_test, iteration);
    }
    virtual void OnTestProgramEnd(const ::iutest::UnitTest& unit_test) IUTEST_CXX_OVERRIDE
    {
        m_default_printer->OnTestProgramEnd(unit_test);
    }
private:
    ::iutest::TestEventListener* m_default_printer;

public:
    /**
     * @brief   QuietResultPrinter に切り替え
    */
    static ::iutest::TestEventListener* SetUp()
    {
        ::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-2016, 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_

#if defined(MS_CPP_UNITTESTFRAMEWORK)
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        iutest_util_vc_unittest.hpp
 * @brief       iris unit test, visual studio 11 C++ Unit Test Framework 対応 ファイル
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2015-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_
#define INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_

//======================================================================
// include
#include "CppUnitTest.h"

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

#ifdef IUTEST_USE_GTEST

#ifdef IIUT_TEST_P_
#  undef IIUT_TEST_P_
#endif
#define IIUT_TEST_P_    TEST_P

#ifdef IIUT_TYPED_TEST_
#  undef IIUT_TYPED_TEST_
#endif
#define IIUT_TYPED_TEST_    TYPED_TEST

#ifdef IIUT_TYPED_TEST_P_
#  undef IIUT_TYPED_TEST_P_
#endif
#define IIUT_TYPED_TEST_P_  TYPED_TEST_P

#endif

/**
 * @private
 * @{
*/

#ifdef IUTEST
#  undef IUTEST
#endif
#define IUTEST(testcase_, testname_)    \
    IUTEST_VCUNIT_I(testcase_, testname_, testcase_##testname_##_class, testcase_##_##testname_);   \
    IUTEST_TEST(testcase_, testname_)

#ifdef IUTEST_F
#  undef IUTEST_F
#endif
#define IUTEST_F(testfixture_, testname_)   \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TEST_F_(testfixture_, testname_)

#ifdef IUTEST_P
#  undef IUTEST_P
#endif
#define IUTEST_P(testfixture_, testname_)   \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TEST_P_(testfixture_, testname_)

#ifdef IUTEST_TYPED_TEST
#  undef IUTEST_TYPED_TEST
#endif
#define IUTEST_TYPED_TEST(testfixture_, testname_)  \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IUTEST_TYPED_TEST_(testfixture_, testname_)

#ifdef IUTEST_TYPED_TEST_P
#  undef IUTEST_TYPED_TEST_P
#endif
#define IUTEST_TYPED_TEST_P(testfixture_, testname_)    \
    IUTEST_VCUNIT_I(testfixture_, testname_, testfixture_##testname_##_class, testfixture_##_##testname_);  \
    IIUT_TYPED_TEST_P_(testfixture_, testname_)


#define IUTEST_VCUNIT_I(testcase_, testname_, className, methodName)    \
    IUTEST_VCUNIT_TEST_CLASS(className) {                               \
    public: TEST_METHOD(methodName) {                                   \
        IUTEST_VCUNIT_EXEC_(testcase_, testname_); }                    \
    IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)                 \
    }

//#define IUTEST_VCUNIT_F(testcase_, testname_, className, methodName)  \
//  IUTEST_VCUNIT_TEST_CLASS(className) {                               \
//  public: TEST_METHOD(methodName) {                                   \
//      IUTEST_VCUNIT_EXEC_(testcase_, testname_); }                    \
//  IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)                 \
//  TEST_CLASS_INITIALIZE(iuSetUp) { testcase_::SetUpTestCase(); }      \
//  TEST_CLASS_CLEANUP(iuTearDown) { testcase_::TearDownTestCase(); }   \
//  }

#define IIUT_VCUNIT_METHOD_ATTRIBUTE(testcase_, methodName)     \
    BEGIN_TEST_METHOD_ATTRIBUTE(methodName)                     \
        TEST_METHOD_ATTRIBUTE(L"TestCase", L#testcase_)         \
    END_TEST_METHOD_ATTRIBUTE()

#define IUTEST_VCUNIT_EXEC_(testcase_, testname_)   \
    Body( "*" #testcase_ "." #testname_ "*" )

#define IUTEST_VCUNIT_TEST_CLASS(className) \
    ONLY_USED_AT_NAMESPACE_SCOPE class className : public ::iuutil::VisualStudio::TestClass<className>

//======================================================================
// class
namespace iuutil {
namespace VisualStudio
{

template<typename T>
class TestClass : public ::Microsoft::VisualStudio::CppUnitTestFramework::TestClass<T>
{
    typedef ::Microsoft::VisualStudio::CppUnitTestFramework::Logger Logger;
public:
    void Body(const char* filter)
    {
        SetUpCppUnitTest();
        ::iutest::IUTEST_FLAG(catch_exceptions) = false;
        ::iutest::IUTEST_FLAG(filter) = filter;
        ::iutest::IUTEST_FLAG(also_run_disabled_tests) = true;
        IUTEST_RUN_ALL_TESTS();
    }
};

/**
 * @brief   Logger
*/
class VCCppUnitTestLogger : public ::iutest::detail::iuLogger
{
    typedef ::Microsoft::VisualStudio::CppUnitTestFramework::Logger Logger;
public:
    virtual void voutput(const char* fmt, va_list va)
    {
        int length = _vscprintf(fmt, va);
        if( length <= 0 )
        {
            return;
        }
        length += 1;
        char* buf = new char [length];
        vsprintf_s(buf, length, fmt, va);
        m_log += buf;
        delete [] buf;

        int pos = m_log.find('\n');
        while(pos >= 0) {
            Logger::WriteMessage(m_log.substr(0, pos).c_str());
            m_log = m_log.substr(pos+1);
            pos = m_log.find('\n');
        }
    }
private:
    ::std::string m_log;
};

/**
 * @brief   Hook 用リポーター
*/
class VCCppUnitTestPartResultReporter : public ::iutest::EmptyTestEventListener
{
public:
    VCCppUnitTestPartResultReporter()
    {
        ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
        listeners.Append(this);
    }
    virtual ~VCCppUnitTestPartResultReporter()
    {
        ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
        listeners.Release(this);
    }
    virtual void OnTestPartResult(const ::iutest::TestPartResult& result)
    {
        // VC にも送る
        if( result.failed() )
        {
            size_t size=0;
            wchar_t buf1[4096]; // TODO: Fixed buffer...
            wchar_t buf2[MAX_PATH];
            ::mbstowcs_s(&size, buf1, sizeof(buf1)/sizeof(buf1[0]), result.message(), _TRUNCATE);
            ::mbstowcs_s(&size, buf2, sizeof(buf2)/sizeof(buf2[0]), result.file_name(), _TRUNCATE);
            ::Microsoft::VisualStudio::CppUnitTestFramework::Assert::Fail(buf1
                , &Microsoft::VisualStudio::CppUnitTestFramework::__LineInfo(buf2, "", result.line_number()) );
        }
    }
};

class VCCppUnitResultPrinter : public ::iutest::TestEventListener
{
public:
    explicit VCCppUnitResultPrinter(::iutest::TestEventListener* default_printer)
        : m_default_printer(default_printer)
    {}
    virtual ~VCCppUnitResultPrinter()
    {
        delete m_default_printer;
    }

public:
    virtual void OnTestProgramStart(const ::iutest::UnitTest& ) {}

    virtual void OnTestIterationStart(const ::iutest::UnitTest& , int ) {}

    virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& ) {}

    virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& ) {}

    virtual void OnTestCaseStart(const ::iutest::TestCase& ) {}

    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);
    }
    virtual void OnTestEnd(const ::iutest::TestInfo& test_info)
    {
        m_default_printer->OnTestEnd(test_info);
    }

    virtual void OnTestCaseEnd(const ::iutest::TestCase& ) {}

    virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& ) {}

    virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& ) {}

    virtual void OnTestIterationEnd(const ::iutest::UnitTest& , int iteration) {}

    virtual void OnTestProgramEnd(const ::iutest::UnitTest& ) {}
private:
    ::iutest::TestEventListener* m_default_printer;

public:
    /**
    * @brief    VCCppUnitResultPrinter に切り替え
    */
    static ::iutest::TestEventListener* SetUp()
    {
        static ::iutest::TestEventListener* p = NULL;
        if( p == NULL )
        {
            ::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
            ::iutest::TestEventListener* default_printer = listeners.Release(listeners.default_result_printer());
            if( default_printer == NULL )
            {
                return NULL;
            }
            p = new VCCppUnitResultPrinter(default_printer);
            listeners.Append(p);
        }
        return p;
    }
};

inline void SetUpCppUnitTest()
{
    {
        static VCCppUnitTestPartResultReporter fake;
#ifndef IUTEST_USE_GTEST
        static VCCppUnitTestLogger logger;
        ::iutest::detail::iuConsole::SetLogger(&logger);
        ::iutest::UnitTestSource::GetInstance().Initialize();
#endif
        VCCppUnitResultPrinter::SetUp();
    }
}

}   // end of namespace VisualStudio
}   // end of namespace iuutil

/**
 * @}
*/


#endif  // INCG_IRIS_IUTEST_UTIL_VC_UNITTEST_HPP_5CA7C30C_2D2A_40A1_A9DE_83EAB4527787_
#endif

/**
 * @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-2016, 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_
