Annotation of nono/lib/test_mystring.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2021 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: 
                      8: #include <vector>
                      9: #include <tuple>
                     10: #include <functional>
                     11: #include "mystring.h"
                     12: 
                     13: // デバッグ文字列を返す
                     14: // プリミティブ型
                     15: template <class T>
                     16: std::string
                     17: ToDebugString(T x) {
                     18:        return std::to_string(x);
                     19: }
                     20: 
                     21: // デバッグ文字列を返す
                     22: // bool 型
                     23: static std::string
                     24: ToDebugString(bool x)
                     25: {
                     26:        return x ? "true" : "false";
                     27: }
                     28: 
                     29: // デバッグ文字列を返す
                     30: // string 型
                     31: static std::string
                     32: ToDebugString(const std::string& x)
                     33: {
                     34:        std::string rv { '"' };
                     35:        // TODO: escape
                     36:        rv += x;
                     37:        rv += '"';
                     38:        return rv;
                     39: }
                     40: 
                     41: static std::string
                     42: ToDebugString(const char *x)
                     43: {
                     44:        return ToDebugString(std::string { x });
                     45: }
                     46: 
                     47: // Tuple with ToDebugString
                     48: 
                     49: // 前方宣言
                     50: template <class... Args>
                     51: class TestTuple;
                     52: 
                     53: // デバッグ文字列を返す
                     54: // TestTuple 型
                     55: template <class... Args>
                     56: std::string
                     57: ToDebugString(const TestTuple<Args...>& x)
                     58: {
                     59:        return x.ToDebugString();
                     60: }
                     61: 
                     62: // オレオレタプル
                     63: template <class... Args>
                     64: class TestTuple : public std::tuple<Args...>
                     65: {
                     66:        // 継承コンストラクタ宣言
                     67:        using std::tuple<Args...>::tuple;
                     68: 
                     69:  public:
                     70:        // デバッグ文字列を返す
                     71:        std::string ToDebugString() const {
                     72:                return ToD(std::index_sequence_for<Args...>{});
                     73:        }
                     74: 
                     75:        // std::get のメンバ関数化
                     76:        // 型が決まらないといけないので [] には出来ない。
                     77:        template <size_t i>
                     78:        auto get() const {
                     79:                return std::get<i>(*this);
                     80:        }
                     81: 
                     82:  private:
                     83:        // このへん参照
                     84:        // https://theolizer.com/cpp-school2/cpp-school2-21/
                     85: 
                     86:        template <size_t... indices>
                     87:        std::string ToD(std::index_sequence<indices...>) const {
                     88:                // get<> にはテンプレート引数を渡さないといけないので
                     89:                // 配列要素数がコンパイル時展開になるようにする。
                     90:                // これでタプルの各要素が型ごとに異なる ToDebugString()
                     91:                // の実体関数を呼び出して、結果の文字列が配列に入っている
                     92:                // 状態になる、ようだ。
                     93:                std::string a[] = {
                     94:                        (::ToDebugString(get<indices>()))...
                     95:                };
                     96: 
                     97:                // a[] をよしなに連結すれば良い
                     98:                std::string rv { '{' };
                     99:                bool first = true;
                    100:                for (const auto& s : a) {
                    101:                        if (first) {
                    102:                                first = false;
                    103:                        } else {
                    104:                                rv += ',';
                    105:                        }
                    106:                        rv += s;
                    107:                }
                    108:                rv += '}';
                    109:                return rv;
                    110:        }
                    111: };
                    112: 
                    113: // テストデータ用テーブル
                    114: template <class... Args>
                    115: class TestTable : public std::vector<TestTuple<Args...> >
                    116: {
                    117:        // 継承コンストラクタ宣言
                    118:        using std::vector<TestTuple<Args... > >::vector;
                    119: };
                    120: 
                    121: 
                    122: // Test
                    123: 
                    124: class TestClass
                    125: {
                    126:  public:
                    127:        virtual ~TestClass() {}
                    128: 
                    129:        template <class T, class R>
                    130:        void Fail(T expectobj, R real) {
                    131:                printf("Failed at: %s but %s\n",
                    132:                        ToDebugString(expectobj).c_str(),
                    133:                        ToDebugString(real).c_str());
                    134:                exit(1);
                    135:        }
                    136: 
                    137:        void Test() {
                    138:                Init();
                    139: 
                    140:                for (auto&& t : testlist) {
                    141:                        printf("Testing: %s ", t.name.c_str());
                    142:                        t.func();
                    143:                        printf("Ok\n");
                    144:                }
                    145:        }
                    146: 
                    147:  protected:
                    148:        // 継承して、TESTDEF マクロを使って testlist を作ってください。
                    149:        virtual void Init() = 0;
                    150: 
                    151:        // テスト関数のリスト
                    152:        class Entry {
                    153:         public:
                    154:                std::string name;
                    155:                std::function<void(void)> func;
                    156:        };
                    157:        std::vector<Entry> testlist;
                    158: 
                    159: #define TESTDEF(x) testlist.push_back({ #x, [&]() { x(); } })
                    160: 
                    161: 
                    162:        template <class T, class TWhere>
                    163:        void xp_eq(T expect, T actual, const TWhere& where)
                    164:        {
                    165:                // eq なので == で比較。演算子オーバーロード対策。
                    166:                if (expect == actual) {
                    167:                        return;
                    168:                }
                    169: 
                    170:                Fail(where, actual);
                    171:        }
                    172: };
                    173: 
                    174: class Test_MyString : public TestClass
                    175: {
                    176:  protected:
                    177:        void Init() override {
                    178:                // TESTDEF マクロに、テスト実行関数の識別子を渡します。
                    179:                TESTDEF(startwith_ignorecase_1);
                    180:                TESTDEF(string_ltrim_1);
                    181:        }
                    182: 
                    183:        void startwith_ignorecase_1() {
                    184:                TestTable<std::string, std::string, bool> table = {
                    185:                        { "ABCDEF", "A", true },
                    186:                        { "ABCDEF", "B", false },
                    187:                        { "ABCDEF", "AB", true },
                    188:                        { "ABCDEF", "BC", false },
                    189:                        { "ABCDEF", "a", true },
                    190:                        { "ABCDEF", "b", false },
                    191:                        { "ABCDEF", "ab", true },
                    192:                        { "ABCDEF", "bc", false },
                    193:                        { "aBCDEF", "a", true },
                    194:                        { "aBCDEF", "b", false },
                    195:                        { "aBCDEF", "ab", true },
                    196:                        { "aBCDEF", "ABcd", true },
                    197:                        { "", "A", false },
                    198:                        { "", "", true },       // ??? これはまだわかる
                    199:                        { "A", "", true },      // ??? 概念的には true だが果たして?
                    200:                };
                    201: 
                    202:                for (auto t : table) {
                    203:                        auto arg0 = t.get<0>();
                    204:                        auto arg1 = t.get<1>();
                    205:                        auto expect = t.get<2>();
                    206: 
                    207:                        xp_eq(expect, starts_with_ignorecase(arg0, arg1), t);
                    208:                }
                    209:        }
                    210: 
                    211:        void string_ltrim_1()
                    212:        {
                    213:                Fail("NOT IMPL", "");
                    214:        }
                    215: };
                    216: 
                    217: int
                    218: main(int ac, char *av[])
                    219: {
                    220:        printf("compiled by ");
                    221: #if defined(__clang_version__)
                    222:        printf("clang %s", __clang_version__);
                    223: #elif defined(__GNUC__) && defined(__VERSION__)
                    224:        printf("gcc %s", __VERSION__);
                    225: #else
                    226:        printf("unknown compiler");
                    227: #endif
                    228:        printf("\n");
                    229: 
                    230:        Test_MyString{}.Test();
                    231:        return 0;
                    232: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.