C++ bitwise operators for std::string

12,314

Solution 1

Once you take out a char out of a string via [] operator you can use all the bitwise operators that you want. C/C++ treats signed/unsigned char's as numerical types (unfortunately).

If you're doing a lot of bitwise operations, you might consider one of the dedicated bit data structures

  • bitset from STL for fixed length bitsets
  • bit_vector from boost for dynamic length bitsets

Solution 2

You can write a generic implementation that works with a functor parameter:

template <typename T>
struct or {
   T operator()( T ch1, T ch2 ) {
      return ch1 | ch2;
   }
};
template <typename T>
struct xor {
   T operator()( T ch1, T ch2 ) {
      return ch1 ^ ch2;
   }
};
template <typename InputIterator1, typename InputIterator2, 
          typename OutputIterator, typename Functor>
void apply( InputIterator1 begin1, InputIterator1 end1,
            InputIterator2 begin2, InputIterator2 end2,
            OutputIterator output, Functor f )
{
   if ( (end1-begin1) != (end2-begin2) ) throw std::exception(); // throw some more meaningful exception...
   while ( begin1 != end1 ) 
   {
      *output++ = f( *begin1++, *begin2++ );
   }
}
// usage:
void string_operations( std::string str1, // by value so we can change it
     std::string const & str2 )
{
   // in place modification
   apply( str1.begin(), str1.end(), str2.begin(), str2.end(), 
          str1.begin(), or<char>() );

   // out of place: copy
   std::string and_string;
   apply( str1.begin(), str1.end(), str2.begin(), str2.end(), 
          std::back_inserter(and_string), and<char>() );
}
Share:
12,314
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    My question is about how to use bitwise operators on C++ std::string. Through overloading or as function does not matter.

    Example for an working XOR/^ function for std::string:

    std::string XOR(std::string value, std::string key)
    {
      std::string retval(value);
      long unsigned int klen = key.length();
      long unsigned int vlen = value.length();
      unsigned long int k = 0;
      unsigned long int v = 0;
      for (; v < vlen; v++) {
        retval[v] = value[v] ^ key[k];
        k = (++k < klen ? k : 0);
      }
      return retval;
    }
    

    What I am missing now is a replacement for NOT/~, AND/& plus OR/|. Example C++ Code (the last two lines would like to have it... :-P):

    //note: matrix_content[][] holds unsigned, *checked* integers...
    //      char(foo) works... 
    std::string vertical_master   = "";
    for (unsigned short int k = 0; k < axis_max; k++) {
      for (unsigned short int l = 0; l < axis_max; l++) {
        horizontal_master += char(matrix_content[l][k]);
        vertical_master   += char(matrix_content[k][l]);
      }
    }
    
    std::string vertical_shift1_0 = vertical_master;
    usigned short int bit = "@"; //<- just an example... chatched via
                                 //   std::string::substr() and std::string::c_str()
    for (unsigned long int x = 0; x < axis_max; x++) {
      vertical_shift1_0 += char(bit);
    }
    std::string vertical_shift2_0;
    for (unsigned long int x = 0; x < axis_max; x++) {
      vertical_shift2_0 += char(0);
    }
    vertical_shift2_0 += vertical_master;
    
    std::string vertical_or  = ~(vertical_shift1 | vertical_shift2);
    std::string vertical_and = ~(vertical_shift1_0 & vertical_shift2_0);
    

    In PHP/Perl I can do nasty :-P things like this

    $vertical_shift1_0 = $vertical_master.str_repeat(chr(0), $axis_max);
    $vertical_shift2_0 = str_repeat(chr(0), $axis_max).$vertical_master;
    $vertical_or       = chunk_split(~($vertical_shift1 | $vertical_shift2), $axis_max, chr(170));
    $vertical_and      = chunk_split(~($vertical_shift1_0 & $vertical_shift2_0), $axis_max, chr(170));
    

    ... and I'm missing it ;-). However XOR works. How can I get AND/OR/NOT?