embed_dispatch_layout.h¶
Source: include/embed_dispatch_layout.h
Compile-time assertions that a struct of function pointers holds its members at consecutive slots, with no padding between them and no member of another type.
Note: This header finds two mistakes, and a call site shows neither. A member added to the struct but not to the list moves each member below it off its slot. Padding between two members does the same, with no edit to the list.
Note: The preprocessor has no loop. Each count of members needs its own line. For that reason, the family below goes up to twenty-four.
Macros¶
EMBED_FUNCTION_POINTER_BYTES¶
Expands to sizeof(void (*)(void)).
Note: A slot index times this gives a byte offset. sizeof(void *) would be wrong here. Code and data pointers differ in width on some targets.
EMBED_TABLE_SLOT¶
#define EMBED_TABLE_SLOT(Table_, member_, slot_) \
EMBED_STATIC_ASSERT(offsetof(Table_, member_) == (size_t)(slot_) * EMBED_FUNCTION_POINTER_BYTES, \
#Table_ "." #member_ " is not at dispatch slot " #slot_)
Asserts one member sits at a given dispatch slot.
[in]:Table_Struct type passed to offsetof.[in]:member_Member name passed to offsetof.[in]:slot_Index, cast tosize_tand multiplied byEMBED_FUNCTION_POINTER_BYTES.
Note: Each
EMBED_TABLE_SLOTS_Nline below expands to this one check.Note: The assertion message holds
Table_,member_, andslot_as strings. A failure names the table, the member, and the index where the member should be.
EMBED_TABLE_SLOTS_1¶
Asserts one member sits at slot 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_The single member's name, at slot 0.
Note: Every longer line in the family expands down to this one. This line calls only
EMBED_TABLE_SLOT.
EMBED_TABLE_SLOTS_2¶
#define EMBED_TABLE_SLOTS_2(Table_, member1_, member2_) \
EMBED_TABLE_SLOTS_1(Table_, member1_) EMBED_TABLE_SLOT(Table_, member2_, 1);
Asserts two members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.
Note: Every longer line in the family works the same way. It expands the line one shorter, then asserts the next index.
EMBED_TABLE_SLOTS_3¶
#define EMBED_TABLE_SLOTS_3(Table_, member1_, member2_, member3_) \
EMBED_TABLE_SLOTS_2(Table_, member1_, member2_) EMBED_TABLE_SLOT(Table_, member3_, 2);
Asserts three members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2, asserted afterEMBED_TABLE_SLOTS_2covers the first two.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with three members.
EMBED_TABLE_SLOTS_4¶
#define EMBED_TABLE_SLOTS_4(Table_, member1_, member2_, member3_, member4_) \
EMBED_TABLE_SLOTS_3(Table_, member1_, member2_, member3_) EMBED_TABLE_SLOT(Table_, member4_, 3);
Asserts four members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3, asserted afterEMBED_TABLE_SLOTS_3covers the first three.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with four members.
EMBED_TABLE_SLOTS_5¶
#define EMBED_TABLE_SLOTS_5(Table_, member1_, member2_, member3_, member4_, member5_) \
EMBED_TABLE_SLOTS_4(Table_, member1_, member2_, member3_, member4_) EMBED_TABLE_SLOT(Table_, member5_, 4);
Asserts five members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4, asserted afterEMBED_TABLE_SLOTS_4covers the first four.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with five members.
EMBED_TABLE_SLOTS_6¶
#define EMBED_TABLE_SLOTS_6(Table_, member1_, member2_, member3_, member4_, member5_, member6_) \
EMBED_TABLE_SLOTS_5(Table_, member1_, member2_, member3_, member4_, member5_) \
EMBED_TABLE_SLOT(Table_, member6_, 5);
Asserts six members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5, asserted afterEMBED_TABLE_SLOTS_5covers the first five.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with six members.
EMBED_TABLE_SLOTS_7¶
#define EMBED_TABLE_SLOTS_7(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_) \
EMBED_TABLE_SLOTS_6(Table_, member1_, member2_, member3_, member4_, member5_, member6_) \
EMBED_TABLE_SLOT(Table_, member7_, 6);
Asserts seven members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6, asserted afterEMBED_TABLE_SLOTS_6covers the first six.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with seven members.
EMBED_TABLE_SLOTS_8¶
#define EMBED_TABLE_SLOTS_8(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_) \
EMBED_TABLE_SLOTS_7(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_) \
EMBED_TABLE_SLOT(Table_, member8_, 7);
Asserts eight members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7, asserted afterEMBED_TABLE_SLOTS_7covers the first seven.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with eight members.
EMBED_TABLE_SLOTS_9¶
#define EMBED_TABLE_SLOTS_9(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_) \
EMBED_TABLE_SLOTS_8(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_) \
EMBED_TABLE_SLOT(Table_, member9_, 8);
Asserts nine members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8, asserted afterEMBED_TABLE_SLOTS_8covers the first eight.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with nine members.
EMBED_TABLE_SLOTS_10¶
#define EMBED_TABLE_SLOTS_10(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_) \
EMBED_TABLE_SLOTS_9(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_) \
EMBED_TABLE_SLOT(Table_, member10_, 9);
Asserts ten members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9, asserted afterEMBED_TABLE_SLOTS_9covers the first nine.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with ten members.
EMBED_TABLE_SLOTS_11¶
#define EMBED_TABLE_SLOTS_11(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_) \
EMBED_TABLE_SLOTS_10(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_) \
EMBED_TABLE_SLOT(Table_, member11_, 10);
Asserts eleven members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10, asserted afterEMBED_TABLE_SLOTS_10covers the first ten.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with eleven members.
EMBED_TABLE_SLOTS_12¶
#define EMBED_TABLE_SLOTS_12(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_) \
EMBED_TABLE_SLOTS_11(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_) \
EMBED_TABLE_SLOT(Table_, member12_, 11);
Asserts twelve members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11, asserted afterEMBED_TABLE_SLOTS_11covers the first eleven.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twelve members.
EMBED_TABLE_SLOTS_13¶
#define EMBED_TABLE_SLOTS_13(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_) \
EMBED_TABLE_SLOTS_12(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_) \
EMBED_TABLE_SLOT(Table_, member13_, 12);
Asserts thirteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12, asserted afterEMBED_TABLE_SLOTS_12covers the first twelve.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with thirteen members.
EMBED_TABLE_SLOTS_14¶
#define EMBED_TABLE_SLOTS_14(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_) \
EMBED_TABLE_SLOTS_13(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_) \
EMBED_TABLE_SLOT(Table_, member14_, 13);
Asserts fourteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13, asserted afterEMBED_TABLE_SLOTS_13covers the first thirteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with fourteen members.
EMBED_TABLE_SLOTS_15¶
#define EMBED_TABLE_SLOTS_15(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_) \
EMBED_TABLE_SLOTS_14(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_) \
EMBED_TABLE_SLOT(Table_, member15_, 14);
Asserts fifteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14, asserted afterEMBED_TABLE_SLOTS_14covers the first fourteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with fifteen members.
EMBED_TABLE_SLOTS_16¶
#define EMBED_TABLE_SLOTS_16(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_) \
EMBED_TABLE_SLOTS_15(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_) \
EMBED_TABLE_SLOT(Table_, member16_, 15);
Asserts sixteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15, asserted afterEMBED_TABLE_SLOTS_15covers the first fifteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with sixteen members.
EMBED_TABLE_SLOTS_17¶
#define EMBED_TABLE_SLOTS_17(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_) \
EMBED_TABLE_SLOTS_16(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_) \
EMBED_TABLE_SLOT(Table_, member17_, 16);
Asserts seventeen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16, asserted afterEMBED_TABLE_SLOTS_16covers the first sixteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with seventeen members.
EMBED_TABLE_SLOTS_18¶
#define EMBED_TABLE_SLOTS_18(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_) \
EMBED_TABLE_SLOTS_17(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_) \
EMBED_TABLE_SLOT(Table_, member18_, 17);
Asserts eighteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17, asserted afterEMBED_TABLE_SLOTS_17covers the first seventeen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with eighteen members.
EMBED_TABLE_SLOTS_19¶
#define EMBED_TABLE_SLOTS_19(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_) \
EMBED_TABLE_SLOTS_18(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_) \
EMBED_TABLE_SLOT(Table_, member19_, 18);
Asserts nineteen members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18, asserted afterEMBED_TABLE_SLOTS_18covers the first eighteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with nineteen members.
EMBED_TABLE_SLOTS_20¶
#define EMBED_TABLE_SLOTS_20(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_) \
EMBED_TABLE_SLOTS_19(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_) \
EMBED_TABLE_SLOT(Table_, member20_, 19);
Asserts twenty members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18.[in]:member20_Member at slot 19, asserted afterEMBED_TABLE_SLOTS_19covers the first nineteen.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twenty members.
EMBED_TABLE_SLOTS_21¶
#define EMBED_TABLE_SLOTS_21(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_) \
EMBED_TABLE_SLOTS_20(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_) \
EMBED_TABLE_SLOT(Table_, member21_, 20);
Asserts twenty-one members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18.[in]:member20_Member at slot 19.[in]:member21_Member at slot 20, asserted afterEMBED_TABLE_SLOTS_20covers the first twenty.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twenty-one members.
EMBED_TABLE_SLOTS_22¶
#define EMBED_TABLE_SLOTS_22(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_, member22_) \
EMBED_TABLE_SLOTS_21(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_) \
EMBED_TABLE_SLOT(Table_, member22_, 21);
Asserts twenty-two members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18.[in]:member20_Member at slot 19.[in]:member21_Member at slot 20.[in]:member22_Member at slot 21, asserted afterEMBED_TABLE_SLOTS_21covers the first twenty-one.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twenty-two members.
EMBED_TABLE_SLOTS_23¶
#define EMBED_TABLE_SLOTS_23(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_, member22_, member23_) \
EMBED_TABLE_SLOTS_22(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_, member22_) \
EMBED_TABLE_SLOT(Table_, member23_, 22);
Asserts twenty-three members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18.[in]:member20_Member at slot 19.[in]:member21_Member at slot 20.[in]:member22_Member at slot 21.[in]:member23_Member at slot 22, asserted afterEMBED_TABLE_SLOTS_22covers the first twenty-two.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twenty-three members.
EMBED_TABLE_SLOTS_24¶
#define EMBED_TABLE_SLOTS_24(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_, member22_, member23_, member24_) \
EMBED_TABLE_SLOTS_23(Table_, member1_, member2_, member3_, member4_, member5_, member6_, member7_, member8_, \
member9_, member10_, member11_, member12_, member13_, member14_, member15_, member16_, \
member17_, member18_, member19_, member20_, member21_, member22_, member23_) \
EMBED_TABLE_SLOT(Table_, member24_, 23);
Asserts twenty-four members sit at consecutive slots from 0.
[in]:Table_Struct type forwarded toEMBED_TABLE_SLOT.[in]:member1_Member at slot 0.[in]:member2_Member at slot 1.[in]:member3_Member at slot 2.[in]:member4_Member at slot 3.[in]:member5_Member at slot 4.[in]:member6_Member at slot 5.[in]:member7_Member at slot 6.[in]:member8_Member at slot 7.[in]:member9_Member at slot 8.[in]:member10_Member at slot 9.[in]:member11_Member at slot 10.[in]:member12_Member at slot 11.[in]:member13_Member at slot 12.[in]:member14_Member at slot 13.[in]:member15_Member at slot 14.[in]:member16_Member at slot 15.[in]:member17_Member at slot 16.[in]:member18_Member at slot 17.[in]:member19_Member at slot 18.[in]:member20_Member at slot 19.[in]:member21_Member at slot 20.[in]:member22_Member at slot 21.[in]:member23_Member at slot 22.[in]:member24_Member at slot 23, asserted afterEMBED_TABLE_SLOTS_23covers the first twenty-three.
Note:
EMBED_TABLE_LAYOUTselects this line for a table with twenty-four members.Warning: This is the longest line in the family. A table with twenty-five members has no line to expand to.
EMBED_NARGalso stops at twenty-four. To raise the limit, add a new line here, one more constant inEMBED_NARG, and one more parameter inEMBED_ARG_N.
EMBED_TABLE_LAYOUT¶
#define EMBED_TABLE_LAYOUT(Table_, ...) \
EMBED_CAT(EMBED_TABLE_SLOTS_, EMBED_NARG(__VA_ARGS__))(Table_, __VA_ARGS__) \
EMBED_STATIC_ASSERT(sizeof(Table_) == (size_t)EMBED_NARG(__VA_ARGS__) * EMBED_FUNCTION_POINTER_BYTES, \
#Table_ " has a member that is not in its dispatch list, or is padded")
Asserts a table's members sit at consecutive slots and that nothing else is in it.
[in]:Table_Struct type forwarded to the arity line and to sizeof.[in]: ... Member names in slot order, one to twenty-four.
Note: The per-member assertions catch a member left out of the list. The size assertion catches padding, since a padded struct is larger than the count times
EMBED_FUNCTION_POINTER_BYTES.Note:
EMBED_CATbuilds the arity line's name fromEMBED_NARG's count of the member list. The caller writes each member once.Warning: A member of some other type changes sizeof(
Table_) and fails the size assertion.
EMBED_TABLE_STORAGE¶
Expands to static const.
Note: Declares a dispatch table. static gives internal linkage. Each translation unit that includes the header gets its own copy. The copies do not collide at link time.
Note: const lets the compiler resolve a call through a table entry to the function directly. That needs a table no other translation unit can reach and no code assigns to.
Note: This macro does not supply
EMBED_UNUSED. Write it on the table as well. A translation unit that calls nothing through the table warns without it.
EMBED_CAT_¶
Expands to left_##right_.
[in]:left_Left operand of ##.[in]:right_Right operand of ##.
**Returns:** The single token that left_ and right_ make together.
Note:
EMBED_CATcalls this macro. ## does not expand its own operands, andEMBED_CATexpands them before it gives them to this macro. CallEMBED_CATwhen either operand is itself a macro.
EMBED_CAT¶
Expands to EMBED_CAT_(left_, right_).
[in]:left_Left operand, forwarded toEMBED_CAT_.[in]:right_Right operand, forwarded toEMBED_CAT_.
**Returns:** The single token that left_ and right_ make together.
Note: This expands its arguments first, then
EMBED_CAT_pastes the results. A macro operand reachesEMBED_CAT_as its value.Note:
EMBED_TABLE_LAYOUTuses this to build anEMBED_TABLE_SLOTS_<n> name fromEMBED_NARG's count.
EMBED_NARG¶
#define EMBED_NARG(...) \
EMBED_NARG_(__VA_ARGS__, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
Expands to EMBED_ARG_N with __VA_ARGS__ followed by the constants 24 down to 0.
[in]: ... The list to count.
**Returns:** The number of arguments, for one to twenty-four arguments.
Note: A count of the arguments turns an arity into a number that
EMBED_CATcan paste into a macro name. The preprocessor has no loop.Warning: An empty list gives 1. The preprocessor cannot tell an empty argument from no argument.
Warning: Twenty-five or more arguments make
EMBED_ARG_Nselect an argument instead of a constant.
EMBED_NARG_¶
Expands to EMBED_ARG_N(__VA_ARGS__).
[in]: ... The list fromEMBED_NARG, followed by the constants 24 down to 0.
**Returns:** The value EMBED_ARG_N selects.
Note:
EMBED_NARGcalls this macro. One more macro level expands the list of the caller beforeEMBED_ARG_Npicks a slot from it.
EMBED_ARG_N¶
#define EMBED_ARG_N(slot1_, slot2_, slot3_, slot4_, slot5_, slot6_, slot7_, slot8_, slot9_, slot10_, slot11_, slot12_, \
slot13_, slot14_, slot15_, slot16_, slot17_, slot18_, slot19_, slot20_, slot21_, slot22_, slot23_, \
slot24_, selected_, ...) \
selected_
Expands to its twenty-fifth argument.
[in]:slot1_Arguments one through twenty-four, discarded.[in]:selected_The twenty-fifth argument.[in]: ... Arguments beyond the twenty-fifth, discarded.
**Returns:** selected_.
Note:
EMBED_NARGappends the constants 24 down to 0 after the caller's list. The caller's arguments push those constants to the right. Whichever one lands twenty-fifth is how many arguments the caller passed.
EMBED_CALL¶
Expands to entry_(&(ArgsType_){__VA_ARGS__}).
[in]:entry_Function called with the address of the literal.[in]:ArgsType_Type of the compound literal.[in]: ... Initializers for the compound literal.
**Returns:** The value entry_ returns.
Note: One pointer costs one register at any arity. A long parameter list fills the registers and spills the rest onto the stack.
Note: C sets to zero each member that the initializer does not name. A compound literal in an argument lives to the end of the block around it. So
entry_can keep the pointer for the full call.Note: Use this macro from C only. No revision of C++ has compound literals. GNU C++ accepts one as an extension, but its lifetime there ends at the full-expression. That breaks the [BORROWS] contract below.
Note:
EMBED_ENTRYandEMBED_ENTRY_Vexpand this macro at a definition site, which is a .c file that compiles as C. A C++ translation unit sees the prototype underEMBED_BEGIN_DECLSand never the expansion.Warning:
entry_receives the address of the literal [BORROWS].
EMBED_ENTRY¶
#define EMBED_ENTRY(entry_prefix_, backend_prefix_, CtxType_, CfgType_, ReturnType_, name_, ...) \
ReturnType_ entry_prefix_##name_(const CfgType_ *args) \
{ \
return EMBED_CALL(backend_prefix_##name_, CtxType_, __VA_ARGS__); \
}
Defines an entry point that returns a value and forwards an argument pack.
[in]:entry_prefix_Prefix of the emitted entry point, pasted ahead ofname_.[in]:backend_prefix_Prefix of the backend the entry calls, pasted ahead ofname_.[in]:CtxType_Type of the compound literal the backend receives.[in]:CfgType_Type the emitted entry takes a pointer to.[in]:ReturnType_Return type of the emitted function.[in]:name_Core name, pasted onto both prefixes.[in]: ... Initializers for theCtxType_literal, written from members of args.
**Returns:** What the backend returns.
Note: One shape for each entry in the library. A caller writes the same call at each module. The entry tests nothing. The backend that it names does each check that an operation needs.
Warning: The initializers dereference args, so it must not be NULL [BORROWS].
EMBED_ENTRY_V¶
#define EMBED_ENTRY_V(entry_prefix_, backend_prefix_, CtxType_, CfgType_, name_, ...) \
void entry_prefix_##name_(const CfgType_ *args) \
{ \
EMBED_CALL(backend_prefix_##name_, CtxType_, __VA_ARGS__); \
}
Defines a void entry point that forwards an argument pack.
[in]:entry_prefix_Prefix of the emitted entry point, pasted ahead ofname_.[in]:backend_prefix_Prefix of the backend the entry calls, pasted ahead ofname_.[in]:CtxType_Type of the compound literal the backend receives.[in]:CfgType_Type the emitted entry takes a pointer to.[in]:name_Core name, pasted onto both prefixes.[in]: ... Initializers for theCtxType_literal, written from members of args.
Note: The same body as
EMBED_ENTRY, without the return. Two macros exist because void does not work asReturnType_. Withvoidthere, the macro still emitsreturn backend(...), and C forbids a return with an expression in a function that returns void.Warning: The initializers dereference args, so it must not be NULL [BORROWS].