📄 bmfunc.h
字号:
{ acc = *word++; BM_INCWORD_BITCOUNT(count, acc); } if (bitcount) // we have a tail to count { acc = (*word) & block_set_table<true>::_left[bitcount-1]; BM_INCWORD_BITCOUNT(count, acc); } return count;}// ----------------------------------------------------------------------/*! Function inverts block of bits @ingroup bitfunc */template<typename T> void bit_invert(T* start, T* end){#ifdef BMVECTOPT VECT_INVERT_ARR(start, end);#else do { start[0] = ~start[0]; start[1] = ~start[1]; start[2] = ~start[2]; start[3] = ~start[3]; start+=4; } while (start < end);#endif}// ----------------------------------------------------------------------/*! @brief Returns "true" if all bits in the block are 1 @ingroup bitfunc */inline bool is_bits_one(const bm::wordop_t* start, const bm::wordop_t* end){ do { bm::wordop_t tmp = start[0] & start[1] & start[2] & start[3]; if (tmp != bm::all_bits_mask) return false; start += 4; } while (start < end); return true;}// ----------------------------------------------------------------------/*! @brief Returns "true" if all bits in the block are 0 @ingroup bitfunc */inline bool bit_is_all_zero(const bm::wordop_t* start, const bm::wordop_t* end){ do { bm::wordop_t tmp = start[0] | start[1] | start[2] | start[3]; if (tmp) return false; start += 4; } while (start < end); return true;}// ----------------------------------------------------------------------// GAP blocks manipulation functions:/*! \brief GAP and functor */inline unsigned and_op(unsigned v1, unsigned v2){ return v1 & v2;}/*! \brief GAP xor functor */inline unsigned xor_op(unsigned v1, unsigned v2){ return v1 ^ v2;}/*! \brief GAP AND operation. Function performs AND logical oparation on gap vectors. If possible function put the result into vect1 and returns this pointer. Otherwise result is put into tmp_buf, which should be twice of the vector size. \param vect1 - operand 1 \param vect2 - operand 2 \param tmp_buf - pointer on temporary buffer \return Result pointer (tmp_buf OR vect1) @ingroup gapfunc*/inline gap_word_t* gap_operation_and(const gap_word_t* BMRESTRICT vect1, const gap_word_t* BMRESTRICT vect2, gap_word_t* BMRESTRICT tmp_buf){ gap_buff_op(tmp_buf, vect1, 0, vect2, 0, and_op); return tmp_buf;}/*! \brief GAP XOR operation. Function performs XOR logical oparation on gap vectors. If possible function put the result into vect1 and returns this pointer. Otherwise result is put into tmp_buf, which should be twice of the vector size. \param vect1 - operand 1 \param vect2 - operand 2 \param tmp_buf - pointer on temporary buffer \return Result pointer (tmp_buf) @ingroup gapfunc*/inline gap_word_t* gap_operation_xor(const gap_word_t* BMRESTRICT vect1, const gap_word_t* BMRESTRICT vect2, gap_word_t* BMRESTRICT tmp_buf){ gap_buff_op(tmp_buf, vect1, 0, vect2, 0, xor_op); return tmp_buf;}/*! \brief GAP OR operation. Function performs OR logical oparation on gap vectors. If possible function put the result into vect1 and returns this pointer. Otherwise result is put into tmp_buf, which should be twice of the vector size. \param vect1 - operand 1 \param vect2 - operand 2 \param tmp_buf - pointer on temporary buffer \return Result pointer (tmp_buf) @ingroup gapfunc*/inline gap_word_t* gap_operation_or(const gap_word_t* BMRESTRICT vect1, const gap_word_t* BMRESTRICT vect2, gap_word_t* BMRESTRICT tmp_buf){// gap_invert(vect1);// gap_temp_invert(vect2); gap_buff_op(tmp_buf, vect1, 1, vect2, 1, and_op);// gap_word_t* res = gap_operation_and(vect1, vect2, tmp_buf);// gap_temp_invert(vect2); gap_invert(tmp_buf);// gap_invert(vect1); return tmp_buf;}/*! \brief GAP SUB (AND NOT) operation. Function performs SUB logical oparation on gap vectors. If possible function put the result into vect1 and returns this pointer. Otherwise result is put into tmp_buf, which should be twice of the vector size. \param vect1 - operand 1 \param vect2 - operand 2 \param tmp_buf - pointer on temporary buffer \return Result pointer (tmp_buf) @ingroup gapfunc*/inline gap_word_t* gap_operation_sub(const gap_word_t* BMRESTRICT vect1, const gap_word_t* BMRESTRICT vect2, gap_word_t* BMRESTRICT tmp_buf){// gap_temp_invert(vect2); gap_buff_op(tmp_buf, vect1, 0, vect2, 1, and_op); // gap_word_t* res = gap_operation_and(vect1, vect2, tmp_buf);// gap_temp_invert(vect2); return tmp_buf;}// ----------------------------------------------------------------------// BIT blocks manipulation functions:/*! \brief Bitblock copy operation. \param dst - destination block. \param src - source block. @ingroup bitfunc*/inline void bit_block_copy(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src){#ifdef BMVECTOPT VECT_COPY_BLOCK(dst, src, src + bm::set_block_size);#else ::memcpy(dst, src, bm::set_block_size * sizeof(bm::word_t));#endif}/*! \brief Plain bitblock AND operation. Function does not analyse availability of source and destination blocks. \param dst - destination block. \param src - source block. @ingroup bitfunc*/inline void bit_block_and(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src){#ifdef BMVECTOPT VECT_AND_ARR(dst, src, src + bm::set_block_size);#else const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*)src; const bm::wordop_t* BMRESTRICT wrd_end = (wordop_t*)(src + bm::set_block_size); bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst; do { dst_ptr[0] &= wrd_ptr[0]; dst_ptr[1] &= wrd_ptr[1]; dst_ptr[2] &= wrd_ptr[2]; dst_ptr[3] &= wrd_ptr[3]; dst_ptr+=4; wrd_ptr+=4; } while (wrd_ptr < wrd_end);#endif}/*! \brief Function ANDs two bitblocks and computes the bitcount. Function does not analyse availability of source blocks. \param src1 - first bit block \param src1_end - first bit block end \param src2 - second bit block @ingroup bitfunc*/inline unsigned bit_block_and_count(const bm::word_t* src1, const bm::word_t* src1_end, const bm::word_t* src2){ unsigned count;#ifdef BMVECTOPT count = VECT_BITCOUNT_AND(src1, src1_end, src2);#else count = 0; do { BM_INCWORD_BITCOUNT(count, src1[0] & src2[0]); BM_INCWORD_BITCOUNT(count, src1[1] & src2[1]); BM_INCWORD_BITCOUNT(count, src1[2] & src2[2]); BM_INCWORD_BITCOUNT(count, src1[3] & src2[3]); src1+=4; src2+=4; } while (src1 < src1_end);#endif return count;}/*! \brief Function XORs two bitblocks and computes the bitcount. Function does not analyse availability of source blocks. \param src1 - first bit block. \param src1_end - first bit block end \param src2 - second bit block. @ingroup bitfunc*/inline unsigned bit_block_xor_count(const bm::word_t* BMRESTRICT src1, const bm::word_t* BMRESTRICT src1_end, const bm::word_t* BMRESTRICT src2){ unsigned count;#ifdef BMVECTOPT count = VECT_BITCOUNT_XOR(src1, src1_end, src2);#else count = 0; do { BM_INCWORD_BITCOUNT(count, src1[0] ^ src2[0]); BM_INCWORD_BITCOUNT(count, src1[1] ^ src2[1]); BM_INCWORD_BITCOUNT(count, src1[2] ^ src2[2]); BM_INCWORD_BITCOUNT(count, src1[3] ^ src2[3]); src1+=4; src2+=4; } while (src1 < src1_end);#endif return count;}/*! \brief Function SUBs two bitblocks and computes the bitcount. Function does not analyse availability of source blocks. \param src1 - first bit block. \param src1_end - first bit block end \param src2 - second bit block. @ingroup bitfunc*/inline unsigned bit_block_sub_count(const bm::word_t* BMRESTRICT src1, const bm::word_t* BMRESTRICT src1_end, const bm::word_t* BMRESTRICT src2){ unsigned count;#ifdef BMVECTOPT count = VECT_BITCOUNT_SUB(src1, src1_end, src2);#else count = 0; do { BM_INCWORD_BITCOUNT(count, src1[0] & ~src2[0]); BM_INCWORD_BITCOUNT(count, src1[1] & ~src2[1]); BM_INCWORD_BITCOUNT(count, src1[2] & ~src2[2]); BM_INCWORD_BITCOUNT(count, src1[3] & ~src2[3]); src1+=4; src2+=4; } while (src1 < src1_end);#endif return count;}/*! \brief Function ORs two bitblocks and computes the bitcount. Function does not analyse availability of source blocks. \param src1 - first bit block \param src1_end - first block end \param src2 - second bit block. @ingroup bitfunc*/inline unsigned bit_block_or_count(const bm::word_t* src1, const bm::word_t* src1_end, const bm::word_t* src2){ unsigned count;#ifdef BMVECTOPT count = VECT_BITCOUNT_OR(src1, src1_end, src2);#else count = 0; do { BM_INCWORD_BITCOUNT(count, src1[0] | src2[0]); BM_INCWORD_BITCOUNT(count, src1[1] | src2[1]); BM_INCWORD_BITCOUNT(count, src1[2] | src2[2]); BM_INCWORD_BITCOUNT(count, src1[3] | src2[3]); src1+=4; src2+=4; } while (src1 < src1_end);#endif return count;}/*! \brief bitblock AND operation. \param dst - destination block. \param src - source block. \returns pointer on destination block. If returned value equal to src means that block mutation requested. NULL is valid return value. @ingroup bitfunc*/inline bm::word_t* bit_operation_and(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src){ BM_ASSERT(dst || src); bm::word_t* ret = dst; if (IS_VALID_ADDR(dst)) // The destination block already exists { if (!IS_VALID_ADDR(src)) { if (IS_EMPTY_BLOCK(src)) { //If the source block is zero //just clean the destination block return 0; } } else { // Regular operation AND on the whole block. bit_block_and(dst, src); } } else // The destination block does not exist yet { if(!IS_VALID_ADDR(src)) { if(IS_EMPTY_BLOCK(src)) { // The source block is empty. // One argument empty - all result is empty. return 0; } // Here we have nothing to do. // Src block is all ON, dst block remains as it is } else // destination block does not exists, src - valid block { if (IS_FULL_BLOCK(dst)) { return const_cast<bm::word_t*>(src); } // Nothng to do. // Dst block is all ZERO no combination required. } } return ret;}/*! \brief Performs bitblock AND operation and calculates bitcount of the result. \param src1 - first bit block. \param src1_end - first bit block end \param src2 - second bit block. \returns bitcount value @ingroup bitfunc*/inline bm::id_t bit_operation_and_count(const bm::word_t* BMRESTRICT src1, const bm::word_t* BMRESTRICT src1_end, const bm::word_t* BMRESTRICT src2){ if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2)) { return 0; } return bit_block_and_count(src1, src1_end, src2);}/*! \brief Performs bitblock SUB operation and calculates bitcount of the result. \param src1 - first bit block. \param src1_end - first bit block end \param src2 - second bit block \returns bitcount value @ingroup bitfunc*/inline bm::id_t bit_operation_sub_count(const bm::word_t* BMRESTRICT src1, const bm::word_t* BMRESTRICT src1_end, const bm::word_t* BMRESTRICT src2){ if (IS_EMPTY_BLOCK(src1)) { return 0; } if (IS_EMPTY_BLOCK(src2)) // nothing to diff { return bit_block_calc_count(src1, src1_end); } return bit_block_sub_count(src1, src1_end, src2);}/*! \brief Performs bitblock OR operation and calculates bitcount of the result. \param src1 - first bit block. \param src1_end - first bit block end \param src2 - second bit block. \returns bitcount value @ingroup bitfunc*/inline bm::id_t bit_operation_or_count(const bm::word_t* BMRESTRICT src1, const bm::word_t* BMRESTRICT src1_end, const bm::word_t* BMRESTRICT src2){ if (IS_EMPTY_BLOCK(src1)) { if (!IS_EMPTY_BLOCK(src2)) return bit_block_calc_count(src2, src2 + (src1_end - src1))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -