#pragma once

//GNU case range extension simulated with preprocessor macros
//
//  usage                 expands to
//  ------------------    -----------------------------------
//  caseN(X):          => case X:
//                        case X + 1:
//                        ...
//                        case X + N - 1:
//
//  case rangeN(X, Y): => case X:
//                        static_assert(Y - X + 1 == N);
//                        case X + 1:
//                        ...
//                        case Y:
//
//the range macro more closely resembles the GNU extension syntax at the cost of
//redundancy. it embeds a static assert between the first two case labels to
//ensure consistency between the chosen macro and the provided macro arguments.

#define check_case_range(x, y, n) static_assert((y) - (x) + 1 == n, "range does not contain " #n " elements"); [[fallthrough]];

#define case1(x) case (x)
#define case2(x) case1(x): case1((x) + 1)
#define case3(x) case1(x): case2((x) + 1)
#define case4(x) case2(x): case2((x) + 2)
#define case5(x) case2(x): case3((x) + 2)
#define case6(x) case3(x): case3((x) + 3)
#define case7(x) case3(x): case4((x) + 3)
#define case8(x) case4(x): case4((x) + 4)
#define case9(x) case4(x): case5((x) + 4)
#define case10(x) case5(x): case5((x) + 5)
#define case11(x) case5(x): case6((x) + 5)
#define case12(x) case6(x): case6((x) + 6)
#define case13(x) case6(x): case7((x) + 6)
#define case14(x) case7(x): case7((x) + 7)
#define case15(x) case7(x): case8((x) + 7)
#define case16(x) case8(x): case8((x) + 8)
#define case17(x) case8(x): case9((x) + 8)
#define case18(x) case9(x): case9((x) + 9)
#define case19(x) case9(x): case10((x) + 9)
#define case20(x) case10(x): case10((x) + 10)
#define case21(x) case10(x): case11((x) + 10)
#define case22(x) case11(x): case11((x) + 11)
#define case23(x) case11(x): case12((x) + 11)
#define case24(x) case12(x): case12((x) + 12)
#define case25(x) case12(x): case13((x) + 12)
#define case26(x) case13(x): case13((x) + 13)
#define case27(x) case13(x): case14((x) + 13)
#define case28(x) case14(x): case14((x) + 14)
#define case29(x) case14(x): case15((x) + 14)
#define case30(x) case15(x): case15((x) + 15)
#define case31(x) case15(x): case16((x) + 15)
#define case32(x) case16(x): case16((x) + 16)
#define case33(x) case16(x): case17((x) + 16)
#define case34(x) case17(x): case17((x) + 17)
#define case35(x) case17(x): case18((x) + 17)
#define case36(x) case18(x): case18((x) + 18)
#define case37(x) case18(x): case19((x) + 18)
#define case38(x) case19(x): case19((x) + 19)
#define case39(x) case19(x): case20((x) + 19)
#define case40(x) case20(x): case20((x) + 20)
#define case41(x) case20(x): case21((x) + 20)
#define case42(x) case21(x): case21((x) + 21)
#define case43(x) case21(x): case22((x) + 21)
#define case44(x) case22(x): case22((x) + 22)
#define case45(x) case22(x): case23((x) + 22)
#define case46(x) case23(x): case23((x) + 23)
#define case47(x) case23(x): case24((x) + 23)
#define case48(x) case24(x): case24((x) + 24)
#define case49(x) case24(x): case25((x) + 24)
#define case50(x) case25(x): case25((x) + 25)
#define case51(x) case25(x): case26((x) + 25)
#define case52(x) case26(x): case26((x) + 26)
#define case53(x) case26(x): case27((x) + 26)
#define case54(x) case27(x): case27((x) + 27)
#define case55(x) case27(x): case28((x) + 27)
#define case56(x) case28(x): case28((x) + 28)
#define case57(x) case28(x): case29((x) + 28)
#define case58(x) case29(x): case29((x) + 29)
#define case59(x) case29(x): case30((x) + 29)
#define case60(x) case30(x): case30((x) + 30)
#define case61(x) case30(x): case31((x) + 30)
#define case62(x) case31(x): case31((x) + 31)
#define case63(x) case31(x): case32((x) + 31)
#define case64(x) case32(x): case32((x) + 32)
#define case65(x) case32(x): case33((x) + 32)
#define case66(x) case33(x): case33((x) + 33)
#define case67(x) case33(x): case34((x) + 33)
#define case68(x) case34(x): case34((x) + 34)
#define case69(x) case34(x): case35((x) + 34)
#define case70(x) case35(x): case35((x) + 35)
#define case71(x) case35(x): case36((x) + 35)
#define case72(x) case36(x): case36((x) + 36)
#define case73(x) case36(x): case37((x) + 36)
#define case74(x) case37(x): case37((x) + 37)
#define case75(x) case37(x): case38((x) + 37)
#define case76(x) case38(x): case38((x) + 38)
#define case77(x) case38(x): case39((x) + 38)
#define case78(x) case39(x): case39((x) + 39)
#define case79(x) case39(x): case40((x) + 39)
#define case80(x) case40(x): case40((x) + 40)
#define case81(x) case40(x): case41((x) + 40)
#define case82(x) case41(x): case41((x) + 41)
#define case83(x) case41(x): case42((x) + 41)
#define case84(x) case42(x): case42((x) + 42)
#define case85(x) case42(x): case43((x) + 42)
#define case86(x) case43(x): case43((x) + 43)
#define case87(x) case43(x): case44((x) + 43)
#define case88(x) case44(x): case44((x) + 44)
#define case89(x) case44(x): case45((x) + 44)
#define case90(x) case45(x): case45((x) + 45)
#define case91(x) case45(x): case46((x) + 45)
#define case92(x) case46(x): case46((x) + 46)
#define case93(x) case46(x): case47((x) + 46)
#define case94(x) case47(x): case47((x) + 47)
#define case95(x) case47(x): case48((x) + 47)
#define case96(x) case48(x): case48((x) + 48)
#define case97(x) case48(x): case49((x) + 48)
#define case98(x) case49(x): case49((x) + 49)
#define case99(x) case49(x): case50((x) + 49)
#define case100(x) case50(x): case50((x) + 50)
#define case101(x) case50(x): case51((x) + 50)
#define case102(x) case51(x): case51((x) + 51)
#define case103(x) case51(x): case52((x) + 51)
#define case104(x) case52(x): case52((x) + 52)
#define case105(x) case52(x): case53((x) + 52)
#define case106(x) case53(x): case53((x) + 53)
#define case107(x) case53(x): case54((x) + 53)
#define case108(x) case54(x): case54((x) + 54)
#define case109(x) case54(x): case55((x) + 54)
#define case110(x) case55(x): case55((x) + 55)
#define case111(x) case55(x): case56((x) + 55)
#define case112(x) case56(x): case56((x) + 56)
#define case113(x) case56(x): case57((x) + 56)
#define case114(x) case57(x): case57((x) + 57)
#define case115(x) case57(x): case58((x) + 57)
#define case116(x) case58(x): case58((x) + 58)
#define case117(x) case58(x): case59((x) + 58)
#define case118(x) case59(x): case59((x) + 59)
#define case119(x) case59(x): case60((x) + 59)
#define case120(x) case60(x): case60((x) + 60)
#define case121(x) case60(x): case61((x) + 60)
#define case122(x) case61(x): case61((x) + 61)
#define case123(x) case61(x): case62((x) + 61)
#define case124(x) case62(x): case62((x) + 62)
#define case125(x) case62(x): case63((x) + 62)
#define case126(x) case63(x): case63((x) + 63)
#define case127(x) case63(x): case64((x) + 63)
#define case128(x) case64(x): case64((x) + 64)

#define range2(x, y) (x): check_case_range(x, y, 2) case1((x) + 1)
#define range3(x, y) (x): check_case_range(x, y, 3) case2((x) + 1)
#define range4(x, y) (x): check_case_range(x, y, 4) case3((x) + 1)
#define range5(x, y) (x): check_case_range(x, y, 5) case4((x) + 1)
#define range6(x, y) (x): check_case_range(x, y, 6) case5((x) + 1)
#define range7(x, y) (x): check_case_range(x, y, 7) case6((x) + 1)
#define range8(x, y) (x): check_case_range(x, y, 8) case7((x) + 1)
#define range9(x, y) (x): check_case_range(x, y, 9) case8((x) + 1)
#define range10(x, y) (x): check_case_range(x, y, 10) case9((x) + 1)
#define range11(x, y) (x): check_case_range(x, y, 11) case10((x) + 1)
#define range12(x, y) (x): check_case_range(x, y, 12) case11((x) + 1)
#define range13(x, y) (x): check_case_range(x, y, 13) case12((x) + 1)
#define range14(x, y) (x): check_case_range(x, y, 14) case13((x) + 1)
#define range15(x, y) (x): check_case_range(x, y, 15) case14((x) + 1)
#define range16(x, y) (x): check_case_range(x, y, 16) case15((x) + 1)
#define range17(x, y) (x): check_case_range(x, y, 17) case16((x) + 1)
#define range18(x, y) (x): check_case_range(x, y, 18) case17((x) + 1)
#define range19(x, y) (x): check_case_range(x, y, 19) case18((x) + 1)
#define range20(x, y) (x): check_case_range(x, y, 20) case19((x) + 1)
#define range21(x, y) (x): check_case_range(x, y, 21) case20((x) + 1)
#define range22(x, y) (x): check_case_range(x, y, 22) case21((x) + 1)
#define range23(x, y) (x): check_case_range(x, y, 23) case22((x) + 1)
#define range24(x, y) (x): check_case_range(x, y, 24) case23((x) + 1)
#define range25(x, y) (x): check_case_range(x, y, 25) case24((x) + 1)
#define range26(x, y) (x): check_case_range(x, y, 26) case25((x) + 1)
#define range27(x, y) (x): check_case_range(x, y, 27) case26((x) + 1)
#define range28(x, y) (x): check_case_range(x, y, 28) case27((x) + 1)
#define range29(x, y) (x): check_case_range(x, y, 29) case28((x) + 1)
#define range30(x, y) (x): check_case_range(x, y, 30) case29((x) + 1)
#define range31(x, y) (x): check_case_range(x, y, 31) case30((x) + 1)
#define range32(x, y) (x): check_case_range(x, y, 32) case31((x) + 1)
#define range33(x, y) (x): check_case_range(x, y, 33) case32((x) + 1)
#define range34(x, y) (x): check_case_range(x, y, 34) case33((x) + 1)
#define range35(x, y) (x): check_case_range(x, y, 35) case34((x) + 1)
#define range36(x, y) (x): check_case_range(x, y, 36) case35((x) + 1)
#define range37(x, y) (x): check_case_range(x, y, 37) case36((x) + 1)
#define range38(x, y) (x): check_case_range(x, y, 38) case37((x) + 1)
#define range39(x, y) (x): check_case_range(x, y, 39) case38((x) + 1)
#define range40(x, y) (x): check_case_range(x, y, 40) case39((x) + 1)
#define range41(x, y) (x): check_case_range(x, y, 41) case40((x) + 1)
#define range42(x, y) (x): check_case_range(x, y, 42) case41((x) + 1)
#define range43(x, y) (x): check_case_range(x, y, 43) case42((x) + 1)
#define range44(x, y) (x): check_case_range(x, y, 44) case43((x) + 1)
#define range45(x, y) (x): check_case_range(x, y, 45) case44((x) + 1)
#define range46(x, y) (x): check_case_range(x, y, 46) case45((x) + 1)
#define range47(x, y) (x): check_case_range(x, y, 47) case46((x) + 1)
#define range48(x, y) (x): check_case_range(x, y, 48) case47((x) + 1)
#define range49(x, y) (x): check_case_range(x, y, 49) case48((x) + 1)
#define range50(x, y) (x): check_case_range(x, y, 50) case49((x) + 1)
#define range51(x, y) (x): check_case_range(x, y, 51) case50((x) + 1)
#define range52(x, y) (x): check_case_range(x, y, 52) case51((x) + 1)
#define range53(x, y) (x): check_case_range(x, y, 53) case52((x) + 1)
#define range54(x, y) (x): check_case_range(x, y, 54) case53((x) + 1)
#define range55(x, y) (x): check_case_range(x, y, 55) case54((x) + 1)
#define range56(x, y) (x): check_case_range(x, y, 56) case55((x) + 1)
#define range57(x, y) (x): check_case_range(x, y, 57) case56((x) + 1)
#define range58(x, y) (x): check_case_range(x, y, 58) case57((x) + 1)
#define range59(x, y) (x): check_case_range(x, y, 59) case58((x) + 1)
#define range60(x, y) (x): check_case_range(x, y, 60) case59((x) + 1)
#define range61(x, y) (x): check_case_range(x, y, 61) case60((x) + 1)
#define range62(x, y) (x): check_case_range(x, y, 62) case61((x) + 1)
#define range63(x, y) (x): check_case_range(x, y, 63) case62((x) + 1)
#define range64(x, y) (x): check_case_range(x, y, 64) case63((x) + 1)
#define range65(x, y) (x): check_case_range(x, y, 65) case64((x) + 1)
#define range66(x, y) (x): check_case_range(x, y, 66) case65((x) + 1)
#define range67(x, y) (x): check_case_range(x, y, 67) case66((x) + 1)
#define range68(x, y) (x): check_case_range(x, y, 68) case67((x) + 1)
#define range69(x, y) (x): check_case_range(x, y, 69) case68((x) + 1)
#define range70(x, y) (x): check_case_range(x, y, 70) case69((x) + 1)
#define range71(x, y) (x): check_case_range(x, y, 71) case70((x) + 1)
#define range72(x, y) (x): check_case_range(x, y, 72) case71((x) + 1)
#define range73(x, y) (x): check_case_range(x, y, 73) case72((x) + 1)
#define range74(x, y) (x): check_case_range(x, y, 74) case73((x) + 1)
#define range75(x, y) (x): check_case_range(x, y, 75) case74((x) + 1)
#define range76(x, y) (x): check_case_range(x, y, 76) case75((x) + 1)
#define range77(x, y) (x): check_case_range(x, y, 77) case76((x) + 1)
#define range78(x, y) (x): check_case_range(x, y, 78) case77((x) + 1)
#define range79(x, y) (x): check_case_range(x, y, 79) case78((x) + 1)
#define range80(x, y) (x): check_case_range(x, y, 80) case79((x) + 1)
#define range81(x, y) (x): check_case_range(x, y, 81) case80((x) + 1)
#define range82(x, y) (x): check_case_range(x, y, 82) case81((x) + 1)
#define range83(x, y) (x): check_case_range(x, y, 83) case82((x) + 1)
#define range84(x, y) (x): check_case_range(x, y, 84) case83((x) + 1)
#define range85(x, y) (x): check_case_range(x, y, 85) case84((x) + 1)
#define range86(x, y) (x): check_case_range(x, y, 86) case85((x) + 1)
#define range87(x, y) (x): check_case_range(x, y, 87) case86((x) + 1)
#define range88(x, y) (x): check_case_range(x, y, 88) case87((x) + 1)
#define range89(x, y) (x): check_case_range(x, y, 89) case88((x) + 1)
#define range90(x, y) (x): check_case_range(x, y, 90) case89((x) + 1)
#define range91(x, y) (x): check_case_range(x, y, 91) case90((x) + 1)
#define range92(x, y) (x): check_case_range(x, y, 92) case91((x) + 1)
#define range93(x, y) (x): check_case_range(x, y, 93) case92((x) + 1)
#define range94(x, y) (x): check_case_range(x, y, 94) case93((x) + 1)
#define range95(x, y) (x): check_case_range(x, y, 95) case94((x) + 1)
#define range96(x, y) (x): check_case_range(x, y, 96) case95((x) + 1)
#define range97(x, y) (x): check_case_range(x, y, 97) case96((x) + 1)
#define range98(x, y) (x): check_case_range(x, y, 98) case97((x) + 1)
#define range99(x, y) (x): check_case_range(x, y, 99) case98((x) + 1)
#define range100(x, y) (x): check_case_range(x, y, 100) case99((x) + 1)
#define range101(x, y) (x): check_case_range(x, y, 101) case100((x) + 1)
#define range102(x, y) (x): check_case_range(x, y, 102) case101((x) + 1)
#define range103(x, y) (x): check_case_range(x, y, 103) case102((x) + 1)
#define range104(x, y) (x): check_case_range(x, y, 104) case103((x) + 1)
#define range105(x, y) (x): check_case_range(x, y, 105) case104((x) + 1)
#define range106(x, y) (x): check_case_range(x, y, 106) case105((x) + 1)
#define range107(x, y) (x): check_case_range(x, y, 107) case106((x) + 1)
#define range108(x, y) (x): check_case_range(x, y, 108) case107((x) + 1)
#define range109(x, y) (x): check_case_range(x, y, 109) case108((x) + 1)
#define range110(x, y) (x): check_case_range(x, y, 110) case109((x) + 1)
#define range111(x, y) (x): check_case_range(x, y, 111) case110((x) + 1)
#define range112(x, y) (x): check_case_range(x, y, 112) case111((x) + 1)
#define range113(x, y) (x): check_case_range(x, y, 113) case112((x) + 1)
#define range114(x, y) (x): check_case_range(x, y, 114) case113((x) + 1)
#define range115(x, y) (x): check_case_range(x, y, 115) case114((x) + 1)
#define range116(x, y) (x): check_case_range(x, y, 116) case115((x) + 1)
#define range117(x, y) (x): check_case_range(x, y, 117) case116((x) + 1)
#define range118(x, y) (x): check_case_range(x, y, 118) case117((x) + 1)
#define range119(x, y) (x): check_case_range(x, y, 119) case118((x) + 1)
#define range120(x, y) (x): check_case_range(x, y, 120) case119((x) + 1)
#define range121(x, y) (x): check_case_range(x, y, 121) case120((x) + 1)
#define range122(x, y) (x): check_case_range(x, y, 122) case121((x) + 1)
#define range123(x, y) (x): check_case_range(x, y, 123) case122((x) + 1)
#define range124(x, y) (x): check_case_range(x, y, 124) case123((x) + 1)
#define range125(x, y) (x): check_case_range(x, y, 125) case124((x) + 1)
#define range126(x, y) (x): check_case_range(x, y, 126) case125((x) + 1)
#define range127(x, y) (x): check_case_range(x, y, 127) case126((x) + 1)
#define range128(x, y) (x): check_case_range(x, y, 128) case127((x) + 1)
