简体   繁体   English

是否有一种简单有效的方法将 bool [8] 的值分配给 std::uint8_t

[英]Is there an easy and efficient way to assign the values of bool [8] to std::uint8_t

Consider the follow variables:考虑以下变量:

std::uint8_t value;

const bool bits[8] = { true, false, false, true,
                       false, false, true, false };

If I was to print out the array of bools to the console如果我要将布尔数组打印到控制台

for (int i = 0; i < 7; i++ )
    std::cout << bits[i];

it would give the following output:它将给出以下输出:

10010010

simple enough and straight forward.足够简单和直接。


What I would like to do is to generate either a constexpr function, a function template, a lambda, or a combination of them that can run either during compile time or runtime depending on the context in which it is being used to where I could take each of these boolean values of 0s and 1s and store them into the variable value above.我想要做的是生成一个 constexpr 函数、一个函数模板、一个 lambda 或它们的组合,它们可以在编译时或运行时运行,具体取决于它被用于我可以采取的上下文每个布尔值 0 和 1 并将它们存储到上面的变量value If the value is known at compile-time then I'd like for this assignment to be resolved.如果该值在编译时已知,那么我希望解决此分配问题。 If the value isn't known at compile-time, then the value will be initialized to 0 until it is updated then it would be used in a runtime context.如果该值在编译时未知,则该值将被初始化为 0,直到它被更新,然后它将在运行时上下文中使用。

However, there is one caveat that isn't obvious at first, but by indexing through the array, the 0 th index of the array will be the LSB bit of the value and the 7 th index will be the MSB.但是,有一个警告一开始并不明显,但是通过对数组进行索引,数组的第 0索引将是该value的 LSB 位,第 7索引将是 MSB。 So the order of bits that you are seeing printed from the screen would have a hex value of 0x92 but the value to be stored needs to be 01001001 which would have the hex value of 0x49 or 73 in decimal and not 146.因此,您从屏幕上看到的位顺序将具有 0x92 的十六进制值,但要存储的值需要是 01001001,它的十六进制值为 0x49 或十进制 73 而不是 146。

The above are members in a class where one is the data value representation and the array of bools is the bit representation.以上是一个类中的成员,其中一个是数据值表示,布尔数组是位表示。 I have a few constructors where one will set the data or value member directly and the other constructors will set the array of bools, but I need for both of these values to stay concurrent with each other through the life of the class object if one updates the other needs to be changed as well.我有一些构造函数,其中一个将直接设置数据或值成员,而其他构造函数将设置 bool 数组,但是如果一个更新,我需要这两个值在类对象的整个生命周期中彼此​​保持并发另一个也需要改变。 Also, the array of bools is a member of a non-named union with a nameless struct of 8 individual bools as a single bit within a bit field.此外,bools 数组是一个无名联合的成员,具有 8 个单独的 bool 的无名结构作为位字段中的一个位。 The class also has an index operator to access the individual bits as single boolean values of 0s or 1s.该类还有一个索引运算符,可以将各个位作为 0 或 1 的单个布尔值访问。


Here is what my class looks like:这是我的班级的样子:

constexpr unsigned BIT_WIDTH(const unsigned bits = 8) { return bits; }

struct Register_8 {
    union {
        bool bits_[BIT_WIDTH()];
        struct {
            bool b0 : 1;
            bool b1 : 1;
            bool b2 : 1;
            bool b3 : 1;

            bool b4 : 1;
            bool b5 : 1;
            bool b6 : 1;
            bool b7 : 1;
        };
    };

    std::uint8_t data_;   

    Register_8() : data_{ 0 } {}
    Register_8(std::uint8_t data) : data_{ data } {

    }

    Register_8(const bool bits[BIT_WIDTH()]) {
        for (unsigned i = 0; i < 8; i++)
            bits_[i] = bits[i];
    }

    Register_8(const bool a, const bool b, const bool c, const bool d,
        const bool e, const bool f, const bool g, const bool h) {
        b0 = a; b1 = b, b2 = c, b3 = d;
        b4 = e, b5 = f, b6 = g, b7 = h;
    }

    const std::uint8_t operator[](std::uint8_t idx) {
        // I know there is no bounds checking here, I'll add that later!
        return bits_[idx];
    }
};

So how can I make each of the values in bits[] to be the individual bits of value where bit[0] is the LSB of value ?那么如何使bits[]中的每个value成为value的单个位,其中bit[0]value的 LSB? I would also like to do this in a context where it will not generate any UB!我还想在不会生成任何 UB 的上下文中执行此操作! Or does there already exist an algorithm within the STL under c++17 that will do this for me?或者在 C++17 下的STL中是否已经存在一种算法可以为我做到这一点? I don't have a C++20 compiler yet... I've tried including the std::uint8_t within the union but it doesn't work as I would like it too and I wouldn't expect it to work either!我还没有 C++20 编译器......我已经尝试在union包含std::uint8_t但它不起作用,因为我也喜欢它,我也不希望它起作用!

I walked away for a little bit and came back to what I was working on... I think the short break had helped.我离开了一会儿,然后又回到了我正在做的事情上……我认为短暂的休息有所帮助。 The suggestion by user Nicol Bolas had also helped by letting me know that I can do it with a constexpr function.用户Nicol Bolas的建议也帮助我知道我可以使用constexpr函数来做到这一点。 Now I don't have to worry about templates or lambdas for this part of the code.现在我不必担心这部分代码的templateslambdas

Here is the function that I have came up with that I believe will assign the bits in the appropriate order.这是我想出的函数,我相信它会按适当的顺序分配位。

constexpr unsigned BIT_WIDTH(const unsigned bits = CHAR_BIT) { return bits; }

constexpr std::uint8_t byte_from_bools(const bool bits[BIT_WIDTH()]) {
    std::uint8_t ret = 0x00;
    std::uint8_t pos = 0x00;
    for (unsigned i = 0; i < BIT_WIDTH(); i++) {
        ret |= static_cast<std::uint8_t>(bits[i]) << pos++; // << pos--;
    }
    return ret;
}

If there are any kind of optimizations that can be done or any bugs or code smells, please let me know...如果有任何可以进行的优化或任何错误或代码异味,请告诉我...


Now, it's just a matter of extracting individual bits and assigning them to my bit-field members, and the track when either one changes to make sure both are updated in a concurrent fashion.现在,只需提取单个位并将它们分配给我的位域成员,并跟踪其中任何一个更改以确保两者以并发方式更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM