// SET OF FUNCTIONS
//########## BIT - BIT
template < typename var_t > inline var_t bit_V (uint8_t b) { return var_t(1) << b; } // Same as usual macros, but this one converts de variable type, so that you can use it in uint8_t to uint64_t for example.
template < typename var_t > inline var_t bit_get (const var_t & V , uint8_t b) { return V & bit_V<var_t>(b); } // Can be used as bool or to get the mask of the bit.
template < typename var_t > inline var_t bit_settled (const var_t & V , uint8_t b) { return V | bit_V<var_t>(b); }
template < typename var_t > inline var_t bit_unsettled (const var_t & V , uint8_t b) { return V &~ bit_V<var_t>(b); }
template < typename var_t > inline void bit_set (var_t & V , uint8_t b) { V |= bit_V<var_t>(b); }
template < typename var_t > inline void bit_unset (var_t & V , uint8_t b) { V &= ~bit_V<var_t>(b); }
template < typename var_t > inline void bit_mod (var_t & V , uint8_t b , bool set) { if (set) bit_set(V,b); else bit_unset(V,b); } // compiler will optimize depending on if 'set' is constant.
template < typename var_t > inline void bit_cpy (var_t & V , const var_t & S , uint8_t b) { var_t t = bit_get(S,b); V |= t; V &~ t; }
template < typename var_t > inline void bit_cpy (var_t & V , const var_t & S , uint8_t bV , uint8_t bM) { bit_mod(V,bV,bit_get(S,bM)); }
/// MULTIPLE BITS:
template < typename var_t > inline void bits_set (var_t & V , const var_t & S) { V |= S; }
template < typename var_t > inline void bits_unset (var_t & V , const var_t & S) { V &= ~S; }
/// ONLY WITH UNSIGNED INTS: 'at' parameters are refered to the less significant bit (lsb), starting at 0 index (a byte would have 7 to 0 bits).
template < typename var_t > void bits_cpy (var_t & V , const var_t & S , uint8_t numBits , uint8_t atlsb = 0 ) { // I choosed not to make this one inline
var_t mask = (~var_t(0)>>(sizeof(var_t)*8 - numBits))<<atlsb;
bits_unset (V , mask) ;
bits_set (V , S & mask ) ;
}
template < typename var_t > void bits_cpy (var_t & V , const var_t & S , uint8_t numBits , uint8_t atVlsb , uint8_t atSlsb) { // I choosed not to make this one inline
bits_cpy (V , (atVlsb>atSlsb)?(S<<(atVlsb-atSlsb)):(S>>(atSlsb-atVlsb)) , numBits , atVlsb) ;
}
template < typename var_t > var_t bits_cpyd (const var_t & V , const var_t & S , uint8_t numBits , uint8_t atlsb = 0 ) {
var_t r = V;
bits_cpy (r,S,numBits,atlsb);
return r;
}
template < typename var_t > var_t bits_cpyd (const var_t & V , const var_t & S , uint8_t numBits , uint8_t atVlsb , uint8_t atSlsb) {
var_t r = V;
bits_cpy (r,S,numBits,atVlsb,atSlsb);
return r;
}
//########## BIT - BIT - EXAMPLE OF USE WITH THE MOST RELEVANT FUNCTIONS:
// I used them inside functions, to get/set two variables inside a class, u and c
void u_set (edrfu_t u) { bits_cpy <uint32_t> (CFG , u , 8 , 2 ,0 );}
edrfu_t u_get () { return bits_cpyd <uint32_t> (0 , CFG , 8 , 0 ,2 );}
void c_set (edrfc_t c) { bits_cpy <uint32_t> (CFG , c , 2 );}
edrfc_t c_get () { return bits_cpyd <uint32_t> (0 , CFG , 2 );}
這很漂亮!我偶爾需要在每個循環計數的環境中操作奇數大小的位串 - 我一定會將其添加到我的一攬子技巧中。 – 2009-08-16 03:53:34
我應該告誡,我只做了一些膚淺的測試,所以我不能保證這種方法能夠100%地工作。 – GRB 2009-08-16 04:07:52
使用unsigned int可以更安全地避免任何有符號位的有趣商業。 – 2009-08-16 06:12:24