C++11テンプレートメタプログラミング-テストキット

1758 ワード

テストキットFixtureは、テスト用例をグループ化するために使用されます.1つのfixtureのすべてのテスト例は、同じ足場を共有し、共通に使用される前置データ、補助関数定義などを含む.テンプレートメタプログラミングにマッピングし、fixtureはメタ関数を定義できる独立した役割ドメインであるべきです.
まずクラス定義でfixtureも実現することを考え,内部のtestcaseはfixtureクラスの埋め込みクラスに相当する.では、fixtureを実装できる補助マクロを定義します.

#define FIXTURE(name) class tlp_fixture_##name

これにより、次のようにFixtureを定義できます.
FIXTURE(TestIntTypeAlgo)
{
    using num1 = __int(10);
    using num2 = __int(2);

    TEST("operator add on int type")
    {
        ASSERT_EQ(__add(num1, num2), __int(12));
    };

    TEST("operator sub on int type")
    {
        ASSERT_EQ(__sub(num1, num2), __int(8));
    };
};

これですべてOKのように見えます.classキーワードを使用します.fixtureクラスの内部定義のすべてのものはデフォルトでprivateで、外部は表示されません.
残念なことに、上記の案には致命的な問題がある.標準規定クラスの内部ではテンプレートの特化を定義できないため,すなわち上述したfixtureの実装によりfixture内部ではモードマッチングを必要とするメタ関数を定義できない.
次に、namespaceを使用してfixtureの実装を求めます.
// "tlp/test/details/Fixture.h"

#define FIXTURE(name) namespace tlp_fixture_##name

実際のTLPにおけるFIXTUREマクロの実装には、テストキットに登録されたコードも含まれているので、ここでの例示的なコードよりも複雑である.いずれにしても、現在のfixture内部では、テスト例で使用する様々な一時メタ関数を定義することができます.
FIXTURE(TestMetaFunctionInFixture)
{
    template
    using LargerType = __if(__bool(sizeof(T) > sizeof(U)), T, U);

    struct TwoBytesType { char dummy[2]; };

    TEST("int should be larger than two bytes")
    {
        ASSERT_EQ(LargerType::Result, int);
    };

    TEST("char should be smaller than two bytes")
    {
        ASSERT_EQ(LargerType::Result, TwoBytesType);
    };
}

テスト
C++11テンプレートメタプログラミング-ディレクトリを返します