[英]How to write a bitmask in c++14 using (something like?) variadic templates
我想写一个有效的方法来在一个字节(或任何其他类型)中写入0和1。
例如,在C语言中,我们可以编写如下代码:
uint8_t x = 0x00;
x|= (1 << 2) | (1 << 4);
在位2和4中写入1(当然,您不使用2和4,而是使用宏来记住位2和4的含义)。
我不喜欢这些方法,因此我编写了以下可变参数模板:
template<typename T>
T bitmask(T p0)
{
return (1 << p0);
}
template<typename T, typename...Position>
T bitmask(T p0, Position... p1_n)
{
return (1 << p0)|bit_mask(p1_n...);
}
template<typename T, typename... Position>
T& write_one(T& x, Position... pos0_n)
{
x|= bit_mask(pos0_n...);
return x;
}
这些工作正常。 您可以这样写:
uint8_t x = 0x00;
write_one(x, 2, 4);
但是我更喜欢另一种解决方案。 我想写一些类似的东西:
write_one<uint8_t>(x, 2, 4); // if x is uint8_t
write_one<uint16_t>(x, 2, 4); // if x is uint16_t
write_one的类型是x的类型(好吧,我知道您不需要写uint8_t和uint16_t类型,为清楚起见,我写了它)。 其他参数始终是数字(实际上,它们是uint8_t)。
如何实现这些目标?
我想编写如下代码:
template<typename T>
T bitmask(uint8_t p0)
{
return (1 << p0);
}
template<typename T>
T bitmask(T p0, uint8_t... p1_n)
{
return (1 << p0)|bit_mask<T>(p1_n...);
}
template<typename T>
T& write_one(T& x, uint8_t... pos0_n)
{
x|= bit_mask<T>(pos0_n...);
return x;
}
非常感谢你。
这两种方法都产生完全相同的高度优化的汇编程序:
#include <utility>
template <int...bits, class Int>
constexpr auto set_bits_a(Int i)
{
using expand = int[];
void(expand{
0,
((i |= (Int(1) << bits)),0)...
});
return i;
}
template <class Int, class...Bits>
constexpr auto set_bits_b(Int i, Bits...bits)
{
using expand = int[];
void(expand{
0,
((i |= (Int(1) << bits)),0)...
});
return i;
}
int get_value();
volatile int x, y;
int main()
{
x = set_bits_a<1, 3, 5>(get_value());
y = set_bits_b(get_value(), 1, 3, 5);
}
输出:
main:
sub rsp, 8
call get_value()
or eax, 42 ; <-- completely optimised
mov DWORD PTR x[rip], eax
call get_value()
or eax, 42 ; <-- completely optimised
mov DWORD PTR y[rip], eax
xor eax, eax
add rsp, 8
ret
y:
x:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.