#include <cstdint>
#include <iostream>
#include <string>

template<uint8_t Bit>
struct set {
	static_assert(Bit < 8);
	static constexpr uint8_t bit = Bit;
	static constexpr bool isNeg = false;
};

template<uint8_t Bit>
struct unset {
	static_assert(Bit < 8);
	static constexpr uint8_t bit = Bit;
	static constexpr bool isNeg = true;
};

template<typename bit, typename... bits>
constexpr uint8_t gen_mask(uint8_t value, uint8_t last_result) {
	uint8_t result = 0;
	if(bit::isNeg ^ ((value & (1 << bit::bit)) == 0)) {
		result = last_result | (1 << bit::bit);
	} else {
		result = last_result & ~(1 << bit::bit);
	}
	if constexpr(sizeof...(bits) == 0) {
		return result;
	} else {
		return gen_mask<bits...>(value, result);
	}
}

template<typename... bits>
constexpr uint8_t gen_mask(uint8_t value) { return gen_mask<bits...>(value, 0); }


int main() {
	uint8_t value = 0b00001111;
	uint8_t mask = gen_mask<set<3>, set<5>, set<6>, unset<0>, unset<7>>(value);
	uint8_t result = value ^ mask;
	std::cout << std::to_string(value) << std::endl;
	std::cout << std::to_string(mask) << std::endl;
	std::cout << std::to_string(result) << std::endl;
}