An interesting problem I\'ve been pondering the past few days is how to copy one integer\'s bits into another integer at a given position in the destination integer. So, for exa
// 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 );}