<future> 注释2:处理枚举类型的 is_enum_v<T> 与 underlying_type_t<T>,支持枚举类型变量的运算的宏函数 _BITMASK_OPS ( launch ) 定义

(12)模板变量 is_enum_v 与类 underlying_type_t,这两个模板变量与模板类,在本头文件 中也会用到。模板变量 is_enum_v 可以判断一个类是不是枚举类。 underlying_type_t 判断一个类的基础类型。

在这里插入图片描述

++ 源码如下:

// 确定 _Ty 是否为枚举类型 determine whether _Ty is an enumerated type 
template <class _Ty>
struct is_enum : bool_constant< __is_enum(_Ty) > {}; 

template <class _Ty>
constexpr bool is_enum_v = __is_enum(_Ty);

//---------------------------------------

template <class _Ty, bool = is_enum_v<_Ty>>
struct _Underlying_type {  using type = __underlying_type(_Ty) ;  };

template <class _Ty>
struct _Underlying_type<_Ty, false> {};

template <class _Ty> // 确定枚举的基础类型 determine underlying根本的 type for enum 
struct underlying_type : _Underlying_type<_Ty> {}; 

template <class _Ty>
using underlying_type_t = typename _Underlying_type<_Ty>::type;

++ 给出一些测试结果:

在这里插入图片描述

++ 关于枚举类型的赋值:

在这里插入图片描述

++ 以及:

在这里插入图片描述

++ 再举例,分析枚举类型的数值计算:

在这里插入图片描述

++ 以及:

在这里插入图片描述

(13) 支持枚举类型变量的运算的宏函数 _BITMASK_OPS ( launch ) 定义,如何处理枚举类型的数值运算,也很重要。 STL 库大师们为我们写好了支持枚举类型的数据的运算的函数。由此宏函数展开到源文件即可。本 头文件也用到了此方面的知识:
源文件中的定义概览:

在这里插入图片描述

++ 可见,内容很多,经展开如下:

在这里插入图片描述

++源码定义如下:

//  该宏函数定义来源于 <type_traits>
constexpr launch operator & (launch _Left, launch _Right) noexcept // return _Left & _Right 
{   using _IntTy = _STD underlying_type_t<launch>; // 经测试 _IntTy 就是 int 类型,推导见上面的注释 
    return static_cast<launch>(static_cast<int>(_Left) & static_cast<int>(_Right));
}   // 以下函数采用简化类型,突出重点。枚举类型只支持与运算,或运算,异或运算,取反运算

launch operator | (launch _Left, launch _Right) noexcept  // return _Left | _Right 
{   return static_cast<launch>(static_cast<int>(_Left) | static_cast<int>(_Right)); }

launch operator^(launch _Left, launch _Right) noexcept  // return _Left ^ _Right 
{   return static_cast<launch>(static_cast<int>(_Left) ^ static_cast<int>(_Right)); }

// return _Left &= _Right    注意:这仨复合运算符函数的形参 1 是左值引用,返回值也是左值引用
launch& operator &= (launch& _Left, launch _Right) { return _Left = _Left & _Right; }

// return _Left |= _Right    调用举例:需使用显式的复合运算符调用, A e &= A a;会报错(与 & 混淆了)
launch& operator |= (launch& _Left, launch _Right) { return _Left = _Left | _Right; }

// return _Left ^= _Right    调用举例:A f = operator^=(A::c, A::a);  
launch& operator ^= (launch& _Left, launch _Right) { return _Left = _Left ^ _Right; }

// return ~_Left       _BITMASK_OPS(launch)的展开结果
launch operator ~ (launch _Left) { return static_cast<launch>(~static_cast<int>(_Left)); }

// return (_Left & _Elements) != launch{}  按位与,测试形参 1 与 2 之间是否有数值重叠,即为包含
bool _Bitmask_includes(launch _Left, launch _Elements) { return (_Left & _Elements) != launch{}; }
// 注意:这俩函数的函数名是固定的,使用了小写字母,与宏函数的形参无关
// return (_Left & _Elements) == _Elements 按位与,测试形参1 是否全部包含了形参 2 的每一位                                                                                                         
bool _Bitmask_includes_all(launch _Left, launch _Elements) { return (_Left & _Elements) == _Elements; }

++ 给个测试

在这里插入图片描述

++ 这里的函数使用的左值引用形式的返回值,那么接受此函数返回的变量到底是不是引用呢?因为这个问题具有共性,在别的文章里另行总结,测试一下

(14)

谢谢

/* * Vhost-user RDMA device : init and packets forwarding * * Copyright (C) 2025 KylinSoft Inc. and/or its affiliates. All rights reserved. * * Author: Xiong Weimin <xiongweimin@kylinos.cn> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef VHOST_RDMA_QUEUE_H_ #define VHOST_RDMA_QUEUE_H_ #include <stdint.h> #include <stdbool.h> #include <linux/types.h> #include "vhost_rdma_ib.h" enum vhost_rdma_ib_wc_opcode { VHOST_RDMA_IB_WC_SEND, VHOST_RDMA_IB_WC_RDMA_WRITE, VHOST_RDMA_IB_WC_RDMA_READ, VHOST_RDMA_IB_WC_RECV, VHOST_RDMA_IB_WC_RECV_RDMA_WITH_IMM, }; enum vhost_rdma_ib_wc_status { /* Operation completed successfully */ VHOST_RDMA_IB_WC_SUCCESS, /* Local Length Error */ VHOST_RDMA_IB_WC_LOC_LEN_ERR, /* Local QP Operation Error */ VHOST_RDMA_IB_WC_LOC_QP_OP_ERR, /* Local Protection Error */ VHOST_RDMA_IB_WC_LOC_PROT_ERR, /* Work Request Flushed Error */ VHOST_RDMA_IB_WC_WR_FLUSH_ERR, /* Bad Response Error */ VHOST_RDMA_IB_WC_BAD_RESP_ERR, /* Local Access Error */ VHOST_RDMA_IB_WC_LOC_ACCESS_ERR, /* Remote Invalid Request Error */ VHOST_RDMA_IB_WC_REM_INV_REQ_ERR, /* Remote Access Error */ VHOST_RDMA_IB_WC_REM_ACCESS_ERR, /* Remote Operation Error */ VHOST_RDMA_IB_WC_REM_OP_ERR, /* Transport Retry Counter Exceeded */ VHOST_RDMA_IB_WC_RETRY_EXC_ERR, /* RNR Retry Counter Exceeded */ VHOST_RDMA_IB_WC_RNR_RETRY_EXC_ERR, /* Remote Aborted Error */ VHOST_RDMA_IB_WC_REM_ABORT_ERR, /* Fatal Error */ VHOST_RDMA_IB_WC_FATAL_ERR, /* Response Timeout Error */ VHOST_RDMA_IB_WC_RESP_TIMEOUT_ERR, /* General Error */ VHOST_RDMA_IB_WC_GENERAL_ERR }; enum vhost_rdma_ib_wr_opcode { VHOST_RDMA_IB_WR_RDMA_WRITE, VHOST_RDMA_IB_WR_RDMA_WRITE_WITH_IMM, VHOST_RDMA_IB_WR_SEND, VHOST_RDMA_IB_WR_SEND_WITH_IMM, VHOST_RDMA_IB_WR_RDMA_READ, }; enum vhost_rdma_queue_type { VHOST_RDMA_QUEUE_SQ, VHOST_RDMA_QUEUE_RQ, }; struct vhost_rdma_sq_req { union { /* Length of sg_list */ __le32 num_sge; /* Length of inline data */ __le16 inline_len; }; /* Flags of the WR properties */ __u8 send_flags; /* WR opcode, enum vhost_rdma_ib_wr_opcode */ __u32 opcode; /* User defined WR ID */ __le64 wr_id; #define VHOST_RDMA_IB_SEND_FENCE (1 << 0) #define VHOST_RDMA_IB_SEND_SIGNALED (1 << 1) #define VHOST_RDMA_IB_SEND_SOLICITED (1 << 2) #define VHOST_RDMA_IB_SEND_INLINE (1 << 3) /* Immediate data (in network byte order) to send */ __le32 imm_data; union { __le32 imm_data; __u32 invalidate_rkey; } ex; union { struct { /* Start address of remote memory buffer */ __le64 remote_addr; /* Key of the remote MR */ __le32 rkey; } rdma; struct { __u64 remote_addr; __u64 compare_add; __u64 swap; __u32 rkey; } atomic; struct { /* Index of the destination QP */ __le32 remote_qpn; /* Q_Key of the destination QP */ __le32 remote_qkey; /* Address Handle */ __le32 ah; } ud; /* Reserved for future */ __le64 reserved[4]; }; /* Inline data */ //__u8 inline_data[512]; /* Reserved for future */ __le32 reserved2[3]; /* Scatter/gather list */ struct vhost_rdma_sge sg_list[]; }; struct vhost_rdma_rq_req { __le32 qpn; /* Length of sg_list */ __le32 num_sge; /* User defined WR ID */ __le64 wr_id; /* Scatter/gather list */ struct vhost_rdma_sge sg_list[]; }; struct vhost_rdma_dma_info { uint32_t length; uint32_t resid; uint32_t cur_sge; uint32_t num_sge; uint32_t sge_offset; uint32_t reserved; union { uint8_t *inline_data; struct vhost_rdma_sge *sge; void *raw; }; }; struct vhost_rdma_send_wqe { struct vhost_rdma_sq_req *wr; struct vhost_rdma_av av; __u32 status; __u32 state; __aligned_u64 iova; __u32 mask; __u32 first_psn; __u32 last_psn; __u32 ack_length; __u32 ssn; __u32 has_rd_atomic; struct vhost_rdma_dma_info dma; }; struct vhost_rdma_cq_req { /* User defined WR ID */ __le64 wr_id; /* Work completion status, enum virtio_ib_wc_status */ __u8 status; /* WR opcode, enum virtio_ib_wc_opcode */ __u8 opcode; /* Padding */ __le16 padding; /* Vendor error */ __le32 vendor_err; /* Number of bytes transferred */ __le32 byte_len; /* Immediate data (in network byte order) to send */ __le32 imm_data; /* Local QP number of completed WR */ __le32 qp_num; /* Source QP number (remote QP number) of completed WR (valid only for UD QPs) */ __le32 src_qp; #define VHOST_RDMA_IB_WC_GRH (1 << 0) #define VHOST_RDMA_WC_WITH_IMM (1 << 1) /* Work completion flag */ __le32 wc_flags; /* Reserved for future */ __le32 reserved[3]; }; void init_send_wqe(struct vhost_rdma_qp *qp, struct vhost_rdma_sq_req *wr, unsigned int mask, unsigned int length, struct vhost_rdma_send_wqe *wqe); void vhost_rdma_handle_sq(void *arg); void vhost_rdma_handle_rq(__rte_unused void *arg); int vhost_rdma_cq_post(struct vhost_rdma_device *dev, struct vhost_rdma_cq *cq, struct vhost_rdma_cq_req *cqe, int solicited); int vhost_rdma_queue_init(struct vhost_rdma_qp *qp, struct vhost_rdma_queue* queue, const char* name, struct vhost_user_queue* vq, size_t elem_size, enum vhost_rdma_queue_type type); void vhost_rdma_queue_cleanup(struct vhost_rdma_qp *qp, struct vhost_rdma_queue* queue); #endif 添加英文注释
最新发布
10-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值