类C结构中自动字段重新排序的方法

托米洛夫·阿纳托利(Tomilov Anatoliy)

有没有一种方法可以在类似C的结构中执行自动字段重新排序我的意思是使用语言功能(例如C和C ++的预处理器以及C ++的模板/类型特征/ etc),这使得可以执行以下宏(类似于Boost.Fusion的样式来适应结构):

REARRANGE(StructureName,
          (int8_t)(FieldName1),
          (int32_t)(FieldName2),
          (int16_t)(FieldName3),
          (int32_t)(FieldName4));
// is equivalent to (without loss of generality):
struct StructureName
{

    int32_t FieldName2;
    int32_t FieldName4;
    int16_t FieldName3;
    int8_t FieldName1;

};

当然,方法应考虑字段的alignof值(以及sizeof),并在可能的情况下考虑#pragma pack当前值。

我知道结果的可移植性很差,但这仅用于本地使用。

必须将字段名称以及相应的类型保存在一起。

目的是减小总结构尺寸。

托米洛夫·阿纳托利(Tomilov Anatoliy)

我找到了C ++ 14解决方案:

#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/repetition/enum.hpp>

#include <utility>

#include <cstddef>

namespace details
{

template< std::size_t /*index*/, typename /*tag*/ >
struct member;

struct pair
{
    std::size_t k, v; 
    constexpr bool operator < (pair const & r) const { return r.k < k; }
};

constexpr void swap(pair & l, pair & r) { pair m = r; r = l; l = m; }

template< int N >
constexpr
void qsort(pair (&a)[N], int const l, int const r)
{ 
    int i = l, j = r;
    pair pivot = a[l + (r - l) / 2];
    while (!(j < i)) { 
        while (a[i] < pivot) ++i;
        while (pivot < a[j]) --j;
        if (!(j < i)) {
            swap(a[i], a[j]);
            ++i;
            --j;
        }
    }
    if (l < j) qsort(a, l, j);
    if (i < r) qsort(a, i, r);
}

template< int N >
struct map
{
    pair a[N];
};

template< int N, std::size_t ...indices >
constexpr
map< N > make_map(pair (&a)[N], std::index_sequence< indices... >)
{
    return {{a[indices]...}};
}

template< int N >
constexpr
map< N > qsort(pair (&&a)[N])
{
    if (1 < N) {
        qsort< N >(a, 0, N - 1);
    }
    return make_map< N >(a, std::make_index_sequence< N >{});
}

}

#define GEN0(z, tag, index, type_name) template<> struct member< index, tag > \
{ BOOST_PP_SEQ_HEAD(type_name) BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(type_name)); };

#define GEN1(z, ignored, index, type_name) {sizeof(BOOST_PP_SEQ_HEAD(type_name)), index},

#define GEN2(z, index, tags) details::member< BOOST_PP_SEQ_HEAD(tags)::map.a[index].v, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(tags)) >

#define GEN(ns, tag, members) \
namespace ns { struct tag; } \
namespace details { BOOST_PP_SEQ_FOR_EACH_I(GEN0, ns::tag, members) } \
namespace details::tags::ns { struct tag { static constexpr auto map = qsort({BOOST_PP_SEQ_FOR_EACH_I(GEN1, %%, members)}); }; } \
namespace ns { struct tag : BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(members), GEN2, (details::tags::ns::tag)(tag)) {}; }

struct T { char c[3]; };

GEN(user::u2, S, ((char)(c))((int)(i))((T)(t)))

#include <cassert>

int main()
{
    using namespace details;
    void(member< 0, user::u2::S >{}.c);
    void(member< 1, user::u2::S >{}.i);
    static_assert(tags::user::u2::S::map.a[0].k == 4);
    static_assert(tags::user::u2::S::map.a[1].k == 3);
    static_assert(tags::user::u2::S::map.a[2].k == 1);
    user::u2::S s{4, {'a', 'b', 'c'}, 'd'};
    assert((void *)&s.i == (void *)&s);
    assert((void *)&s.t < (void *)&s.c);
    static_assert(sizeof(s) == 8);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在C ++中重新利用基类的字段?

来自分类Dev

自动重新排序dplyr中的因子水平

来自分类Dev

类中字段的C#覆盖方法

来自分类Dev

汇编中结构参数的字段如何排序?

来自分类Dev

在多字段中隐藏重新排序按钮

来自分类Dev

结构作为模板类C ++的字段

来自分类Dev

C中的结构字段分配

来自分类Dev

在 C 中扩展结构字段

来自分类Dev

DataGridView自动重新排序

来自分类Dev

重新加载Java类中的静态字段

来自分类Dev

在快速错误处理中重新抛出类/结构实例方法

来自分类Dev

对子对象父结构中的JS对象重新排序

来自分类Dev

对子对象-父结构中的JS对象重新排序

来自分类Dev

jqgrid 数据在折叠网格中自动重新排序

来自分类Dev

C ++类std :: numeric_limits中的字段与方法

来自分类Dev

在WooCommerce 3中对结帐字段进行重新排序

来自分类Dev

在嵌套数据框中重新排序字段

来自分类Dev

在 Django 中扩展 AbstractUser 时,如何重新排序管理字段?

来自分类Dev

在C ++中对结构数组进行排序

来自分类Dev

在C ++中对用户定义的结构进行排序

来自分类Dev

在C中对结构元素进行排序

来自分类Dev

在C中对结构数组进行排序

来自分类常见问题

如何从方法中改变结构的字段?

来自分类Dev

C:如何对结构中的值进行排序和子排序

来自分类Dev

C:如何对结构中的值进行排序和子排序

来自分类Dev

将JSON字段升级为类结构的最佳方法

来自分类Dev

Java类中的字段排序在NetBeans中不起作用

来自分类Dev

在C ++中从main调用类中的结构

来自分类Dev

如何正确初始化作为 ANSI-C 中 RPC 自动生成结构字段的字符串