获取 POD 结构的打包以计算元素偏移

问题描述

我正在编写一个函数来计算我的 pod_reflection 库中 POD 结构中元素的偏移量。 Complete header link

要计算下一个元素的偏移量,我需要知道结构的打包值(可以通过 #pragma pack(N) 设置)。 我假设 alignof 运算符产生这个值,因为例如,对于 pack(1) 它返回 1:

#pragma pack(push,1)
struct packed
{
    char a;
    int b;
};
#pragma pack(pop)

static_assert(alignof(packed) == 1,"");

我发现我错了。如果结构包含 double(8 个字节),则 alignof 产生 8。因此计算出的偏移量将无效。

这是我用来计算偏移量的代码

        template<typename POD,typename TupleFeed = basic_Feed>
        constexpr size_t pod_packing()
        {
            return alignof(POD);
        }

        // Todo: check this function!
        template<size_t I,typename POD,typename TupleFeed>
        class pod_elem_offset
        {
            static_assert(!std::is_same<undeduced,pod_element_t<I,POD,TupleFeed>>::value,"Can't get an offset for an undeduced POD element!");

            template<size_t Indx>
            constexpr static size_t pod_elem_size()
            {
                return sizeof(pod_element_t<Indx,TupleFeed>);
            }

        public:
            constexpr static std::ptrdiff_t packing = pod_packing<POD,TupleFeed>();

            constexpr static std::ptrdiff_t value()
            {
                return get_value(tag_s<0>(),0);
            }

        private:
            // stop case
            constexpr static std::ptrdiff_t get_value(tag_s<I>,size_t offset)
            {
                return offset;
            }

            // general recursion
            template<size_t N>
            constexpr static std::ptrdiff_t get_value(tag_s<N>,size_t offset)
            {
                static_assert(!std::is_same<undeduced,pod_element_t<N,"Can't get an offset for a POD element: Failed to deduce one of POD elements' type!");

                // Todo: implement with packing
                return get_value(tag_s<N + 1>(),!((offset + pod_elem_size<N>()) % packing) ||
                                 packing - (offset + pod_elem_size<N>()) % packing >= pod_elem_size<N + 1>() ?
                                 offset + pod_elem_size<N>() :
                                 offset + pod_elem_size<N>() +
                                 packing - (offset + pod_elem_size<N>()) % packing
                );
            }

        };

如何推导出结构体的填充值进行填充计算?


我想出了一个解决方法。不确定它是否足以满足所有可能的包装。

        template<typename POD>
        constexpr size_t pod_packing()
        {
            return sizeof(POD) % 4 ?
                   sizeof(POD) % 4 :
                   4;
        }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)