Оптимизация класса с помощью побитовых операций
Есть класс и он хранит восемь свойств, каждое свойство может иметь четыре состояния. Уверен что это дает возможность оптимизировать запись состояния экземпляра, используя всего лишь одно 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';
}