{"id":31904493,"url":"https://github.com/cwksc/macro-library","last_synced_at":"2025-10-13T13:50:32.709Z","repository":{"id":86679442,"uuid":"198972806","full_name":"CWKSC/macro-library","owner":"CWKSC","description":"A Library for Macro (C/C++). Advanced skill of Macro. Delayed expansion, distinguishing number of parameters, expanding different macros according parameter number, Implement default parameters, create unique variable names, Even try catch in C","archived":false,"fork":false,"pushed_at":"2024-08-14T07:28:19.000Z","size":7443,"stargazers_count":29,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-14T08:48:24.832Z","etag":null,"topics":["c","cpp","loop","macro","macros","metaprogramming"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CWKSC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-26T07:53:24.000Z","updated_at":"2024-08-14T08:48:27.475Z","dependencies_parsed_at":null,"dependency_job_id":"9bb58b54-6886-4bd4-9a54-1c1faf00fde9","html_url":"https://github.com/CWKSC/macro-library","commit_stats":null,"previous_names":["cwksc/macro-library"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CWKSC/macro-library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CWKSC%2Fmacro-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CWKSC%2Fmacro-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CWKSC%2Fmacro-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CWKSC%2Fmacro-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CWKSC","download_url":"https://codeload.github.com/CWKSC/macro-library/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CWKSC%2Fmacro-library/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015357,"owners_count":26085686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cpp","loop","macro","macros","metaprogramming"],"created_at":"2025-10-13T13:49:24.802Z","updated_at":"2025-10-13T13:50:32.703Z","avatar_url":"https://github.com/CWKSC.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MacroLib\n\n\u003e [!CAUTION]\n\u003e \n\u003e This is no longer maintained and used\n\u003e\n\u003e Also, don't use too much C marco in project, it is just for fun\n\nLanguage: [zh](https://github.com/CWKSC/macro-library/blob/master/README_zh.md)\n\nSome updates in the new preprocessor of Visual Studio 2019 and C++20 version\n\nThe new version marco lib in here: [my-library-cpp-macro](https://github.com/CWKSC/my-library-cpp-macro)\n\n## What is it?\n\nThis repository contains some advanced techniques for macros. For example:\n\n* Delayed expansion\n* Distinguishing the number of parameters\n* Expanding different macros according to the parameter integer\n* Implementing default parameters\n* Create unique variable names\n* Even try catch in C, of course not traditional one\n* ... and a bunch of derived syntactic sugar\n\n___\n\nLet see the `main.c` for demo: \n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cmath.h\u003e\n#include \u003cstdarg.h\u003e\n\n#include \"SupportingMacro.h\"\n#include \"ForLoopMacro.h\"\n#include \"ArrayLoopingMacro.h\"\n#include \"LinkedList.h\"\n#include \"TryCatch.h\"\n\n\ndouble check_negative_function(double input) {\n    if (input \u003c 0) {\n        throw(isNegative_FromFunction);\n    }\n}\n\ndouble my_sqrt(double input) {\n    check_negative_function(input);\n\n    checkThrow(isNegative_FromFunction_changeName, 0.0);\n\n    return sqrt(input);\n}\n\n\n#define check_negative_macro(input) \\\n    if (input \u003c 0) { \\\n        giveThrow(isNegative_FromMacro); \\\n    }\n\ndouble my_sqrt2(double input) {\n\n    // 檢查值是否小於零，默認 給出 名爲 isNegative 的錯誤\n    check_negative_macro(input);\n\n    // 檢查有否發生錯誤，有則回傳括弧内的值\n    check(0.0);\n\n    return sqrt(input);\n}\n\n\n\nint main() {\n\n\n    // easyFor() //\n    // 1 至 100 的總和 //\n    printf(\"[easyFor] 1 至 100 的總和\\n\");\n    int sum_easyFor = 0;\n    easyFor(i, 1, 100) {  // for(int i = 1; i \u003c= 100; i++)\n        sum_easyFor += i;\n    }\n    printf(\"%d\\n\", sum_easyFor);\n    ln;\n\n\n    // flexFor() //\n    // 1 至 100 內奇數的總和 //\n    printf(\"[flexFor] 1 至 100 內奇數的總和\\n\");\n    int sum_flexFor = 0;\n    flexFor(i, 1, 100, i += 2) {  // for(int i = 1; i \u003c= 100; i+=2)\n        sum_flexFor += i;\n    }\n    printf(\"%d\\n\", sum_flexFor);\n    ln;\n\n\n    // ffor() //\n    // 計算 [1 至 100] 及 [101 至 200 內奇數] 的總和 //\n    printf(\"[ffor] 計算 [1 至 100] 及 [101 至 200 內奇數] 的總和\\n\");\n    int sum_ffor = 0;\n    ffor(i, 1, 100) {  //easyFor(i, 1, 100)\n        sum_ffor += i;\n    }\n    ffor(i, 101, 200, i += 2) {  //flexFor(i, 101, 200, i+=2)\n        sum_ffor += i;\n    }\n    printf(\"%d\\n\", sum_ffor);  //12550\n    ln;\n\n\n    // loopBy() //\n    // 遍歷 x * y 的二維陣列 //\n    printf(\"[loopBy] 遍歷 x * y 的二維陣列\\n\");\n#define x 3\n#define y 4\n    int array2d_loopBy[x][y] = { 0 };\n    loopBy(i, x) {  // for(int i = 0; i != x; i++)\n        loopBy(j, y) {  // for(int j = 0; j != x ; j++)\n            printf(\"%d\", array2d_loopBy[i][j]);\n        }\n        ln;\n    }\n#undef x\n#undef y\n    ln;\n\n\n    // pureLoop() //\n    // 輸出 n * n 的 * 方陣 //\n    printf(\"[pureLoop] 輸出 n * n 的 * 方陣\\n\");\n#define n 3\n    pureLoop(n) {\n        pureLoop(n) {\n            printf(\"* \");\n        }\n        ln;\n    }\n#undef n\n    ln;\n\n\n    // loop2d() //\n    // 遍歷 x * y 的二維陣列 //\n    printf(\"[loop2d] 遍歷 x * y 的二維陣列\\n\");\n#define x 3\n#define y 4\n    int array2d_loop2d[x][y] = { 0 };\n    loop2d(i, x, j, y) {\n        printf(\"%d\", array2d_loop2d[i][j]);\n        rightCurlyBracket\n    ln;\n    }\n    ln;\n#undef x\n#undef y\n\n\n    // loop2d() //\n    // 二維純粹循環 //\n    // 輸出 n * n 的 * 方陣 //\n    printf(\"[loop2d] 輸出 n * n 的 * 方陣 \\n\");\n#define n 3\n    loop2d(n, n) {\n        printf(\"* \");\n        rightCurlyBracket\n    ln;\n    }\n#undef n\n    ln;\n\n\n    // forech() //\n    // 遍歷陣列 //\n    printf(\"[forech] 遍歷陣列\\n\");\n    int arr[10] = { 1, 3, 4, 2, 1, 2, 3, 7, 9, 1 };\n    forech(int, x, arr,\n        printf(\"%d \", x);\n    );\n    ln2;\n\n    // ifTrue() //\n    printf(\"[ifTrue]\\n\");\n    printf(\"ifTrue(1, printf(\\\"OK\\\")) : \");  ifTrue(1, printf(\"OK\")); ln;\n    printf(\"ifTrue(0, printf(\\\"OK\\\")) : \");  ifTrue(0, printf(\"OK\")); ln;\n    ln;\n\n    // ifFalse() //\n    printf(\"[ifFalse]\\n\");\n    printf(\"ifFalse(1, printf(\\\"OK\\\")) : \"); ifFalse(1, printf(\"OK\")); ln;\n    printf(\"ifFalse(0, printf(\\\"OK\\\")) : \"); ifFalse(0, printf(\"OK\")); ln;\n    ln;\n\n    // conditionalOperator() // \n    printf(\"[conditionalOperator]\\n\");\n    printf(\"conditionalOperator(1, exp1, exp2) : \");\n    conditionalOperator(1, printf(\"exp1\"), printf(\"exp2\");); ln;\n    printf(\"conditionalOperator(0, exp1, exp2) : \");\n    conditionalOperator(0, printf(\"exp1\"), printf(\"exp2\"););\n    ln2;\n\n    // Linked List //\n    printf(\"[Linked List] push 10, push 12, print\\n\");\n    createLinkedList(list);\n    pushFrontByValue(list, 10);\n    pushFrontByValue(list, 12);\n    printLinkedList(list);\n    freeLinkedList(list);\n    ln2;\n\n\n    // 有發生錯誤，由 throw() 拋出 isNegative_FromFunction 錯誤\n    check_negative_function(-10); try(ex1);\n\n    // 有發生錯誤，由 check_negative_function() 的 throw() 拋出 isNegative_FromFunction 錯誤\n    // checkThrow() 把錯誤名稱改爲 isNegative_FromFunction_changeName 錯誤\n    my_sqrt(-20); try(ex2);\n\n    // 有發生錯誤，由 giveThrow() 拋出 isNegative_FromMacro 錯誤\n    // 由 check() 檢測並再次拋出\n    my_sqrt2(-30); try(ex3);\n\n    // 沒有發生錯誤\n    my_sqrt2(40); try(ex4);\n\n    // 有發生錯誤，由 giveThrow() 拋出 isNegative_FromMacro 錯誤\n    // 由 check() 檢測並再次拋出\n    // try() 把它改名為 tryChangeExeptionName 錯誤\n    my_sqrt2(-50); try(ex5, tryChangeExeptionName);\n\n    system(\"pause\");\n\n    // 正常到達這裏，會回傳括弧内的值 //\n    catchStart(0);\n    catch (isNegative_FromFunction) {\n        printf(\"[isNegative_FromFunction] exception is happened!\\n\");\n    }\n    catch (isNegative_FromFunction_changeName) {\n        printf(\"[isNegative_FromFunction_changeName] exception is happened!\\n\");\n    }\n    catch (isNegative_FromMacro) {\n        printf(\"[isNegative_FromMacro] exception is happened!\\n\");\n    }\n    catch (tryChangeExeptionName) {\n        printf(\"[changeExeptionName] exception is happened!\\n\");\n    }\n    finally() {\n        printf(\"[finally()] exception is happened!\\n\\n\");\n    }\n    // 標出所有返回點\n    catchEnd(ex1, ex2, ex3, ex4, ex5)\n\n\n    system(\"pause\");\n    return 0;\n}\n```\n\n### And the corresponding output:\n\n```c\n[easyFor] 1 至 100 的總和\n5050\n\n[flexFor] 1 至 100 內奇數的總和\n2500\n\n[ffor] 計算 [1 至 100] 及 [101 至 200 內奇數] 的總和\n12550\n\n[loopBy] 遍歷 x * y 的二維陣列\n0000\n0000\n0000\n\n[pureLoop] 輸出 n * n 的 * 方陣\n* * *\n* * *\n* * *\n\n[loop2d] 遍歷 x * y 的二維陣列\n0000\n0000\n0000\n\n[loop2d] 輸出 n * n 的 * 方陣\n* * *\n* * *\n* * *\n\n[forech] 遍歷陣列\n1 3 4 2 1 2 3 7 9 1\n\n[ifTrue]\nifTrue(1, printf(\"OK\")) : OK\nifTrue(0, printf(\"OK\")) :\n\n[ifFalse]\nifFalse(1, printf(\"OK\")) :\nifFalse(0, printf(\"OK\")) : OK\n\n[conditionalOperator]\nconditionalOperator(1, exp1, exp2) : exp1\nconditionalOperator(0, exp1, exp2) : exp2\n\n[Linked List] push 10, push 12, print\n12 10\n\n[isNegative_FromFunction] exception is happened!\n[finally()] exception is happened!\n\n[isNegative_FromFunction_changeName] exception is happened!\n[finally()] exception is happened!\n\n[isNegative_FromMacro] exception is happened!\n[finally()] exception is happened!\n\n[changeExeptionName] exception is happened!\n[finally()] exception is happened!\n```\n\n___\n\n#### `SupportingMacro.h`\n\n```c\n#pragma once\n\n#define ln putchar('\\n')\n#define ln2 printf(\"\\n\\n\")\n\n#define refer *\n\n#define leftBracket (\n#define rightBracket )\n\n#define leftCurlyBracket {\n#define rightCurlyBracket }\n\n#define comma ,\n\n#define midLayer(...) __VA_ARGS__\n#define eatComma(...) ,##__VA_ARGS__\n\n#define linkMacro_body(a, b) a ## b\n#define linkMacro(a, b) linkMacro_body(a, b)\n#define uniqueVarName(name) linkMacro(name, __COUNTER__)\n#define uniqueVarName2(name) linkMacro_body leftBracket name, __COUNTER__ )\n\n#define get1th(a1, ...) a1\n#define get2th(a1, a2, ...) a2\n#define get3th(a1, a2, a3, ...) a3\n#define get4th(a1, a2, a3, a4, ...) a4\n#define get5th(a1, a2, a3, a4, a5, ...) a5\n#define get6th(a1, a2, a3, a4, a5, a6, ...) a6\n#define get7th(a1, a2, a3, a4, a5, a6, a7, ...) a7\n#define get8th(a1, a2, a3, a4, a5, a6, a7, a8, ...) a8\n#define get9th(a1, a2, a3, a4, a5, a6, a7, a8, a9, ...) a9\n#define get10th(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10\n\n#define get1thVS(...) midLayer( get1th(__VA_ARGS__) )\n#define get2thVS(...) midLayer( get2th(__VA_ARGS__) )\n#define get3thVS(...) midLayer( get3th(__VA_ARGS__) )\n#define get4thVS(...) midLayer( get4th(__VA_ARGS__) )\n#define get5thVS(...) midLayer( get5th(__VA_ARGS__) )\n#define get6thVS(...) midLayer( get6th(__VA_ARGS__) )\n#define get7thVS(...) midLayer( get7th(__VA_ARGS__) )\n#define get8thVS(...) midLayer( get8th(__VA_ARGS__) )\n#define get9thVS(...) midLayer( get9th(__VA_ARGS__) )\n#define get10thVS(...) midLayer( get10th(__VA_ARGS__) )\n\n#define parameterNum(...) get10thVS(__VA_ARGS__, 9, 8, 7, 6 , 5, 4, 3, 2, 1)\n\n#define select0_1(m0, m1, ...) get3th leftBracket eatComma(__VA_ARGS__), m1, m0 )\n#define select0_2(m0, m1, m2, ...) get4th leftBracket eatComma(__VA_ARGS__), m2, m1, m0)\n#define select0_3(m0, m1, m2, m3, ...) get5th leftBracket eatComma(__VA_ARGS__), m3, m2, m1, m0)\n#define select0_4(m0, m1, m2, m3, m4, ...) get6th leftBracket eatComma(__VA_ARGS__), m4, m3, m2, m1, m0)\n#define select0_5(m0, m1, m2, m3, m4, m5, ...) get7th leftBracket eatComma(__VA_ARGS__), m5, m4, m3, m2, m1, m0)\n#define select0_6(m0, m1, m2, m3, m4, m5, m6, ...) get8th leftBracket eatComma(__VA_ARGS__), m6, m5, m4, m3, m2, m1, m0)\n#define select0_7(m0, m1, m2, m3, m4, m5, m6, m7, ...) get9th leftBracket eatComma(__VA_ARGS__), m7, m6, m5, m4, m3, m2, m1, m0)\n#define select0_8(m0, m1, m2, m3, m4, m5, m6, m7, m8, ...) get10th leftBracket eatComma(__VA_ARGS__), m8, m7, m6, m5, m4, m3, m2, m1, m0)\n\n#define select0_1VS(va_args, m0, m1) select_va_args_0_1(m1, m0, va_args)\n#define select0_2VS(va_args, m0, m1, m2) select_va_args_0_2(m2, m1, m0, va_args)\n#define select0_3VS(va_args, m0, m1, m2, m3) select_va_args_0_3(m3, m2, m1, m0, va_args)\n#define select0_4VS(va_args, m0, m1, m2, m3, m4) select_va_args_0_4(m4, m3, m2, m1, m0, va_args)\n#define select0_5VS(va_args, m0, m1, m2, m3, m4, m5) select_va_args_0_5(m5, m4, m3, m2, m1, m0, va_args)\n#define select0_6VS(va_args, m0, m1, m2, m3, m4, m5, m6) select_va_args_0_6(m6, m5, m4, m3, m2, m1, m0, va_args)\n#define select0_7VS(va_args, m0, m1, m2, m3, m4, m5, m6, m7) select_va_args_0_7(m7, m6, m5, m4, m3, m2, m1, m0, va_args)\n#define select0_8VS(va_args, m0, m1, m2, m3, m4, m5, m6, m7, m8) select_va_args_0_8(m8, m7, m6, m5, m4, m3, m2, m1, m0, va_args)\n```\n\n### `ArrayLoopingMacro.h`\n\n```c\n#pragma once\n\n#include \"SupportingMacro.h\"\n\n#define arrLength(arr) \\\n    (sizeof(arr) / sizeof(arr[0]))\n\n// 針對遍歷陣列，默認 var 從 0 開始，遞增為 1\n#define loopBy(var, ...) \\\n    for(int var = 0; var != __VA_ARGS__; var++)\n\n// 不在乎循環變量，只要單純的重複次數\n#define pureLoop(...) \\\n    loopBy( uniqueVarName(macroLoopTempVar), __VA_ARGS__)\n\n// 合併兩個 Looping\n#define loop(p1, ...)                  \\\n    select0_1(pureLoop(p1),            \\\n              loopBy(p1, __VA_ARGS__), \\\n              __VA_ARGS__)\n\n// 遍歷二維陣列的 Looping\n#define loopBy2d(var1, times1, var2, ...) \\\n    loopBy(var1, times1){                 \\\n        loopBy(var2, __VA_ARGS__)\n\n// 二維純粹循環\n#define pureLoop2d(n, ...) \\\n    pureLoop(n){           \\\n        pureLoop(__VA_ARGS__)\n\n// 合併兩個二維 Looping\n#define loop2d(p1, p2, ...)                    \\\n    select0_2(pureLoop2d(p1, p2),              \\\n              pureLoop2d(p1, p2, __VA_ARGS__), \\\n              loopBy2d(p1, p2, __VA_ARGS__),   \\\n              __VA_ARGS__)\n```\n\n### `ForLoopMacro.h`\n\n```c\n#pragma once\n\n#include \"SupportingMacro.h\"\n\n// 簡化版 for loop\n#define easyFor(var, start, end) \\\n    for(int var = start; var \u003c= end; var++)\n\n// 較靈活的 for loop\n#define flexFor(var, start, end, ...) \\\n    for(int var = start; var \u003c= end; __VA_ARGS__)\n\n// 合併以上兩個 for loop\n#define ffor(var, start, end, ...)                   \\\n    select0_1(easyFor(var, start, end),              \\\n              flexFor(var, start, end, __VA_ARGS__), \\\n              __VA_ARGS__)\n\n// forech\n#define forech(type, var, list, ...) \\\n    loopBy(i, arrLength(list)){      \\\n        type var = list[i];          \\\n        __VA_ARGS__                  \\\n\t}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcwksc%2Fmacro-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcwksc%2Fmacro-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcwksc%2Fmacro-library/lists"}