Оптимизация класса с помощью побитовых операций

Есть класс и он хранит восемь свойств, каждое свойство может иметь четыре состояния. Уверен что это дает возможность оптимизировать запись состояния экземпляра, используя всего лишь одно 16-битное число, выделив по два бита каждому свойству. Но для этого нужно вспомнить как работать с побитовыми операциями. Я в этом немного плаваю. Надеюсь вы мне поможете :)

Написал такой интерфейс, внутри set методов необходимо теперь двигаться вдоль числа на два шага, чтобы записывать каждое свойство в свои родные два бита. Внутри get методов возвращать значения двух конкретных бит.

class TasteQualities final {
        uint16_t _bQualities;
    public:
        TasteQualities();
        explicit TasteQualities(uint16_t qualities)
            noexcept :
            _bQualities(qualities)
        {};

        void SetSalty   (std::bitset<2> value); // соленый
        void SetAcidic  (std::bitset<2> value); // кислый
        void SetSugary  (std::bitset<2> value); // сладкий
        void SetBitter  (std::bitset<2> value); // горький
        void SetFatty   (std::bitset<2> value); // жирный
        void SetStiff   (std::bitset<2> value); // жесткий
        void SetHarsh   (std::bitset<2> value); // терпкий
        void SetRaw     (std::bitset<2> value); // сырой

        std::bitset<2> getSalty();
        std::bitset<2> getAcidic();
        std::bitset<2> getSugary();
        std::bitset<2> getBitter();
        std::bitset<2> getFatty();
        std::bitset<2> getStiff();
        std::bitset<2> getHarsh();
        std::bitset<2> getRaw();
    };

Ответы (1 шт):

Автор решения: Sergey Inozemcev

Итоговый результат:

class TasteQualities final {
        uint16_t _bQualities;
        
    public:
        static constexpr std::bitset<2> None        { 0 };
        static constexpr std::bitset<2> Abstinently { 0x1 };
        static constexpr std::bitset<2> Saturated   { 0x2 };
        static constexpr std::bitset<2> Redundantly { 0x3 };

        static constexpr std::bitset<16> Salty      { 0x0003 };
        static constexpr std::bitset<16> Acidic     { 0x000C };
        static constexpr std::bitset<16> Sugary     { 0x0030 };
        static constexpr std::bitset<16> Bitter     { 0x00C0 };
        static constexpr std::bitset<16> Fatty      { 0x0300 };
        static constexpr std::bitset<16> Stiff      { 0x0C00 };
        static constexpr std::bitset<16> Harsh      { 0x3000 };
        static constexpr std::bitset<16> Raw        { 0xC000 };

        TasteQualities() {};
        explicit TasteQualities(uint16_t qualities)
            noexcept :
            _bQualities(qualities)
        {};

        void SetSalty(std::bitset<2> value);    // соленый
        void SetAcidic(std::bitset<2> value); // кислый
        void SetSugary(std::bitset<2> value); // сладкий
        void SetBitter(std::bitset<2> value); // горький
        void SetFatty(std::bitset<2> value); // жирный
        void SetStiff(std::bitset<2> value); // жесткий
        void SetHarsh(std::bitset<2> value); // терпкий
        void SetRaw(std::bitset<2> value);  // сырой

        std::bitset<2> getSalty();
        std::bitset<2> getAcidic();
        std::bitset<2> getSugary();
        std::bitset<2> getBitter();
        std::bitset<2> getFatty();
        std::bitset<2> getStiff();
        std::bitset<2> getHarsh();
        std::bitset<2> getRaw();

        void toStream(std::ostream& cout) noexcept;
        void toUlongStream(std::ostream& cout) noexcept;

    };

void TasteQualities::SetSalty(std::bitset<2> value) {
    _bQualities |= value.to_ulong();
}
void TasteQualities::SetAcidic(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 2;
}
void TasteQualities::SetSugary(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 4;
}
void TasteQualities::SetBitter(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 6;
}
void TasteQualities::SetFatty(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 8;
}
void TasteQualities::SetStiff(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 10;
}
void TasteQualities::SetHarsh(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 12;
}
void TasteQualities::SetRaw(std::bitset<2> value) {
    _bQualities |= value.to_ulong() >> 14;
}

std::bitset<2> TasteQualities::getSalty() {
    return _bQualities & TasteQualities::Salty.to_ulong();
}
std::bitset<2> TasteQualities::getAcidic() {
    return (_bQualities & TasteQualities::Acidic.to_ulong()) >> 2;
}
std::bitset<2> TasteQualities::getSugary() {
    return (_bQualities & TasteQualities::Sugary.to_ulong()) >> 4;
}
std::bitset<2> TasteQualities::getBitter() {
    return (_bQualities & TasteQualities::Bitter.to_ulong()) >> 6;
}
std::bitset<2> TasteQualities::getFatty() {
    return (_bQualities & TasteQualities::Fatty.to_ulong()) >> 8;
}
std::bitset<2> TasteQualities::getStiff() {
    return (_bQualities & TasteQualities::Stiff.to_ulong()) >> 10;
}
std::bitset<2> TasteQualities::getHarsh() {
    return (_bQualities & TasteQualities::Harsh.to_ulong()) >> 12;
}
std::bitset<2> TasteQualities::getRaw() {
    return (_bQualities & TasteQualities::Raw.to_ulong()) >> 14;
}

void TasteQualities::toUlongStream(std::ostream& cout) noexcept {
    cout << std::bitset<16>(_bQualities) << '\n';
}

void TasteQualities::toStream(std::ostream& cout) noexcept {
    cout << "salty: " << getSalty() << '\n';
    cout << "acidic: " << getAcidic() << '\n';
    cout << "sugary: " << getSugary() << '\n';
    cout << "bitter: " << getBitter() << '\n';
    cout << "fatty: " << getFatty() << '\n';
    cout << "stiff: " << getStiff() << '\n';
    cout << "harsh: " << getHarsh() << '\n';
    cout << "raw: " << getRaw() << '\n';
    
}
→ Ссылка