对齐静态字符串文本
Aligning static string literals
我有一个静态的结构数组:
struct CommandStruct
{
char* data;
unsigned ans_size;
};
static const CommandStruct commands[] =
{
{ "Some literal", 28 },
{ "Some other literal", 29 },
{ "Yet another literal", 8 },
};
我希望字符串是 16 字节对齐的。可以直接实现吗?我可能会像__declspec(align(16)) static const char some_command_id[] = "my literal"
一样单独定义每个文字,但这一团糟。我需要在单个代码块中进行所有初始化。
对于 C++11,以下内容可能会有所帮助: https://ideone.com/IDEdY0
#include <cstdint>
// Sequence of char
template <char...Cs> struct char_sequence
{
template <char C> using push_back = char_sequence<Cs..., C>;
};
// Remove all chars from char_sequence from ' '
template <typename, char...> struct strip_sequence;
template <char...Cs>
struct strip_sequence<char_sequence<>, Cs...>
{
using type = char_sequence<Cs...>;
};
template <char...Cs, char...Cs2>
struct strip_sequence<char_sequence<' ', Cs...>, Cs2...>
{
using type = char_sequence<Cs2...>;
};
template <char...Cs, char C, char...Cs2>
struct strip_sequence<char_sequence<C, Cs...>, Cs2...>
{
using type = typename strip_sequence<char_sequence<Cs...>, Cs2..., C>::type;
};
// struct to create a aligned char array
template <std::size_t Alignment, typename chars> struct aligned_string;
template <std::size_t Alignment, char...Cs>
struct aligned_string<Alignment, char_sequence<Cs...>>
{
alignas(Alignment) static constexpr char str[sizeof...(Cs)] = {Cs...};
};
template <std::size_t Alignment, char...Cs>
alignas(Alignment) constexpr
char aligned_string<Alignment, char_sequence<Cs...>>::str[sizeof...(Cs)];
// helper to get the i_th character (` ` for out of bound)
template <std::size_t I, std::size_t N>
constexpr char at(const char (&a)[N]) { return I < N ? a[I] : ' '; }
// helper to check if the c-string will not be truncated
template <std::size_t max_size, std::size_t N>
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<at<(I) + 0>(S)>::push_back<at<(I) + 1>(S)>
::push_back<at<(I) + 2>(S)>::push_back<at<(I) + 3>(S)>
::push_back<at<(I) + 4>(S)>::push_back<at<(I) + 5>(S)>
::push_back<at<(I) + 6>(S)>::push_back<at<(I) + 7>(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<char_sequence<>
PUSH_BACK_128(S, 0)
>::type::template push_back<check_size<128>(S) ? ' ' : ' '>
// Macro to return an aligned c-string
#define MAKE_ALIGNED_STRING(ALIGNMENT, S)
aligned_string<ALIGNMENT, MAKE_CHAR_SEQUENCE(S)>::str
所以你有:
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 },
};
浏览了一下 boost 之后,我设法制作了一些东西,它只是自动执行单独的文字构造,(我还制作了所有数组元素的枚举):
#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)
};
相关文章:
- 在 C++ 中从 8 位 ASCII 字符创建 7 位 ASCII 文本字符串
- cin>>gender 和 cin>>*gender ( c 样式文本字符串)有什么区别
- 是否可以动态检查文本字符串是否是 C++ 中给定类的成员?
- 用Zlib解压缩文本字符串
- 将文本字符串作为常量字符 * 参数传递会导致代码分析器错误
- 来自文本字符串或某种其他机制的代码类自动生成器
- 函数读取最大和min int值,并用文本字符串返回
- 模板代码和文本字符串
- 声明具有常量引用与常量变量的常量文本字符串
- 加密给定的文本字符串-Caesar Cipher
- 如何使用键盘输入和sf ::文本在SFML中添加一种文本框以显示文本字符串
- 在C++代码中,如何让用户在2个文本字符串之间输入一个数字
- 如何将文本从一个文件复制到另一个文件,然后将文本字符串的第一个字母转换为大写
- 从文本字符串推断类型
- 跟踪内存中的文本字符串
- 将字符串变量与整数和文本字符串连接起来的 C++ 字符串流
- 将 char 数组分配给文本字符串 - C++
- 如何修复将文本字符串附加到 C 字符串的错误
- 使用C++读取不同长度的多个文本字符串
- 在C++中创建原始文本字符串,类似于 C# 的"@ string"