#ifndef _AL_FUNCTION_HPP #define _AL_FUNCTION_HPP #include #include #include #include uint32_t ones = 0b11111111111111111111111111111111; uint32_t mask_1 = 0b01010101010101010101010101010101; uint32_t remains_1 = 0b00000000000000000000000000000001; uint32_t shift_1 = 1; uint32_t mask_2 = 0b00110011001100110011001100110011; uint32_t remains_2 = 0b00000000000000000000000000000011; uint32_t shift_2 = 2; uint32_t mask_3 = 0b00001111000011110000111100001111; uint32_t remains_3 = 0b00000000000000000000000000001111; uint32_t shift_3 = 4; uint32_t mask_4 = 0b00000000111111110000000011111111; uint32_t remains_4 = 0b00000000000000000000000011111111; uint32_t shift_4 = 8; template class Function { public: Function(): _function_values(0) { static_assert(not std::numeric_limits::is_signed); } explicit Function(STORAGE val): _function_values(val) { static_assert(not std::numeric_limits::is_signed); } explicit Function(std::string val): _function_values(0) { static_assert(not std::numeric_limits::is_signed); assert(("bad input string size", val.size() == VALUES_COUNT)); STORAGE cur_dig = 1; for (auto it = val.rbegin(); it != val.rend(); ++it) { if ( *it == '0' ) { // nothing to do here } else if ( *it == '1' ) { _function_values += cur_dig; } else { assert(("bad input string", false)); } cur_dig *= 2; } } std::string string() const { std::string res(VALUES_COUNT, '0'); STORAGE tmp_val = _function_values; for (size_t ind = 0; ind < VALUES_COUNT; ++ind) { char cur_ch = tmp_val % 2 == 0 ? '0' : '1'; res[VALUES_COUNT - ind - 1] = cur_ch; tmp_val /= 2; } return res; } Function operator and (Function other) const { return Function(_function_values & other._function_values); } Function operator or (Function other) const { return Function(_function_values | other._function_values); } Function operator xor(Function other) const { return Function(_function_values ^ other._function_values); } bool operator < (Function other) const { return _function_values < other._function_values; } bool operator == (Function other) const { return _function_values == other._function_values; } STORAGE at(STORAGE index) const { return (_function_values >> index) % 2; } Function var_negation(STORAGE var_index) { // var_index should be in 1..VARS_COUNT STORAGE mask, remains, shift; switch (var_index) { case 1: mask = mask_1; remains = remains_1; shift = shift_1; break; case 2: mask = mask_2; remains = remains_2; shift = shift_2; break; case 3: mask = mask_3; remains = remains_3; shift = shift_3; break; case 4: mask = mask_4; remains = remains_4; shift = shift_4; break; default: assert(false); } STORAGE first_part = (_function_values & (~mask)) >> shift; STORAGE second_part = (_function_values & mask) << shift; return Function(first_part | second_part); } STORAGE value() const { return _function_values; } private: STORAGE _function_values; }; #endif // _AL_FUNCTION_HPP