Allineare i valori letterali stringa statici

Ho una matrice statica di strutture:

struct CommandStruct { char* data; unsigned ans_size; }; static const CommandStruct commands[] = { { "Some literal", 28 }, { "Some other literal", 29 }, { "Yet another literal", 8 }, }; 

E voglio che le stringhe siano allineate a 16 byte. È ansible raggiungerlo direttamente? Potrei farla __declspec(align(16)) static const char some_command_id[] = "my literal" definendo separatamente ogni letterale, come __declspec(align(16)) static const char some_command_id[] = "my literal" , ma questo è un casino. Ho bisogno di tutte le inizializzazioni in un singolo blocco di codice.

Con C ++ 11, seguire può aiutare: https://ideone.com/IDEdY0

 #include  // Sequence of char template  struct char_sequence { template  using push_back = char_sequence; }; // Remove all chars from char_sequence from '\0' template  struct strip_sequence; template  struct strip_sequence, Cs...> { using type = char_sequence; }; template  struct strip_sequence, Cs2...> { using type = char_sequence; }; template  struct strip_sequence, Cs2...> { using type = typename strip_sequence, Cs2..., C>::type; }; // struct to create a aligned char array template  struct aligned_string; template  struct aligned_string> { alignas(Alignment) static constexpr char str[sizeof...(Cs)] = {Cs...}; }; template  alignas(Alignment) constexpr char aligned_string>::str[sizeof...(Cs)]; // helper to get the i_th character (`\0` for out of bound) template  constexpr char at(const char (&a)[N]) { return I < N ? a[I] : '\0'; } // helper to check if the c-string will not be truncated template  constexpr bool check_size(const char (&)[N]) { static_assert(N <= max_size, "string too long"); return N <= max_size; } // Helper macros to build char_sequence from c-string #define PUSH_BACK_8(S, I) \ ::push_back(S)>::push_back(S)> \ ::push_back(S)>::push_back(S)> \ ::push_back(S)>::push_back(S)> \ ::push_back(S)>::push_back(S)> #define PUSH_BACK_32(S, I) \ PUSH_BACK_8(S, (I) + 0) PUSH_BACK_8(S, (I) + 8) \ PUSH_BACK_8(S, (I) + 16) PUSH_BACK_8(S, (I) + 24) #define PUSH_BACK_128(S, I) \ PUSH_BACK_32(S, (I) + 0) PUSH_BACK_32(S, (I) + 32) \ PUSH_BACK_32(S, (I) + 64) PUSH_BACK_32(S, (I) + 96) // Macro to create char_sequence from c-string (limited to 128 chars) #define MAKE_CHAR_SEQUENCE(S) \ strip_sequence \ PUSH_BACK_128(S, 0) \ >::type::template push_back(S) ? '\0' : '\0'> // Macro to return an aligned c-string #define MAKE_ALIGNED_STRING(ALIGNMENT, S) \ aligned_string::str 

E così hai:

 static const CommandStruct commands[] = { { MAKE_ALIGNED_STRING(16, "Some literal"), 28 }, { MAKE_ALIGNED_STRING(16, "Some other literal"), 29 }, { MAKE_ALIGNED_STRING(16, "Yet another literal"), 8 }, }; 

Sfogliando un po ‘, sono riuscito a creare qualcosa che automatizza solo la costruzione di letterali separati, (faccio anche enum di tutti gli elementi dell’array):

 #define CMD_TUPLE ( \ (cmdCommandOne, "The first command", 1900),\ (cmdCommandTwo, "The second one", 1),\ (cmdAnother, "Another command", 11)) #define CMD_SEQ BOOST_PP_TUPLE_TO_SEQ(CMD_TUPLE) #define CMD_MAKE_ENUM(r, data, elem) BOOST_PP_TUPLE_ELEM(0, elem), enum Commands { BOOST_PP_SEQ_FOR_EACH(CMD_MAKE_ENUM, , CMD_SEQ) cmdLast }; #define CMD_MAKE_STRING(r, data, elem) \ __declspec(align(16)) static const char \ BOOST_PP_CAT(cmd_, BOOST_PP_TUPLE_ELEM(0, elem))[] = BOOST_PP_TUPLE_ELEM(1, elem); BOOST_PP_SEQ_FOR_EACH(CMD_MAKE_STRING, , CMD_SEQ) #define CMD_MAKE_ARRAY(r, data, elem) \ { BOOST_PP_CAT(cmd_, BOOST_PP_TUPLE_ELEM(0, elem)), \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_REST_N(2, BOOST_PP_TUPLE_TO_SEQ(elem))) }, static const CommandStruct commands[] = { BOOST_PP_SEQ_FOR_EACH(CMD_MAKE_ARRAY, , CMD_SEQ) };