Convert vector<byte> to vector<short>?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: Convert vector<byte> to vector<short>?

  1. #1
    Join Date
    Nov 2009
    Posts
    18

    Question Convert vector<byte> to vector<short>?

    Hi all,

    I'd like a code-concise way to find a modulo (2^16) sum of a vector<uint8_t>. i.e. The bytes are grabbed in pairs, and summed into an unsigned short (uint16_t). I tried making a vector<uint16_t> from the vector<uint8_t> using reinterpret_cast and the vector constructor that takes iterators (third one here http://www.cplusplus.com/reference/stl/vector/vector/)...figuring I could then use the accumulate algorithm...but the bytes were swapped (wrong endianness, I guess).

    Thoughts?

    Thanks.


    Code:
    //---------------------------------------------------------------------------
    
    #include <vector>
    #include <iostream>
    #include <iomanip>
    #include <stdint>
    #pragma hdrstop
    
    using std::vector;
    using std::cout;
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    int main(int argc, char* argv[])
    {
        vector<uint8_t> byteVec;
        for (uint8_t b=0; b<0x12; b++)
            byteVec.push_back(b);
    
        //vector<uint16_t> shortVec(byteVec);
        typedef vector<uint16_t>::iterator iter_t;
        iter_t begin = reinterpret_cast<iter_t>(byteVec.begin());
        iter_t end   = reinterpret_cast<iter_t>(byteVec.end());
        vector<uint16_t> shortVec(begin, end);
    
        //cout << std::hex << std::setw(4) << std::setfill('0');
        for (iter_t it=shortVec.begin(); it != shortVec.end(); it++) {
            cout << std::hex << std::setw(4) << std::setfill('0') << *it << ' ';
        }
    
        return 0;
    }
    //---------------------------------------------------------------------------

    Yields
    0100 0302 0504 0706 0908 0b0a 0d0c 0f0e 1110

  2. #2
    Join Date
    Apr 1999
    Posts
    27,427

    Re: Convert vector<byte> to vector<short>?

    Firstly, a vector<uint8_t> and a vector<uint16_t> are two totally different types -- one is an elephant and the other an albatross. Just because they use the same template class doesn't change that fact.

    Calling reinterpret_cast on them is implementation-defined behaviour and not portable.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Convert vector<byte> to vector<short>?

    I think, the best way would be to create a state-aware functor for this and use for_each to transform the vector.

    Some quickly hacked example:
    Code:
    #include <stdint.h>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    class int_8_to_16 {
      bool _bigendian;
      bool _first;
      uint16_t _value;
      std::vector<uint16_t>& _vec;
    public:
      int_8_to_16(std::vector<uint16_t>& vec, bool bigendian) : _bigendian(bigendian), _first(true), _value(0), _vec(vec) {}
      void operator()(uint8_t byte) {
        if (_first) {
          _value = byte;
          _first = false;
        } else {
          _value = _bigendian ? (_value<<8)+byte : (byte<<8)+_value;
          _vec.push_back(_value);
          _value = 0;
          _first = true;
        }
      }
    };
    
    int main() {
      std::vector<uint8_t> v1;
      v1.push_back(1);
      v1.push_back(45);
      v1.push_back(2);
      v1.push_back(200);
    
      std::vector<uint16_t> v2;
    
      for_each(v1.begin(), v1.end(), int_8_to_16(v2, true));
      std::copy(v2.begin(), v2.end(), std::ostream_iterator<uint16_t>(std::cout, " "));
      std::cout << "\n";
    
      std::vector<uint16_t> v3;
    
      for_each(v1.begin(), v1.end(), int_8_to_16(v3, false));
      std::copy(v3.begin(), v3.end(), std::ostream_iterator<uint16_t>(std::cout, " "));
      std::cout << "\n";
    }
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  4. #4
    Join Date
    Nov 2009
    Posts
    18

    Resolved Re: Convert vector<byte> to vector<short>?

    Thanks for your input.

    I find functors a bit obtuse, and I've spent more time on this than I should...just brute-forcing it...

    Code:
        uint16_t sum = 0;
        for (int i=0; i<byteVec.size(); i++) {
            sum += ((i&#37;2==0) ? byteVec[i]<<8 : byteVec[i]);
        }

  5. #5
    Join Date
    Dec 2005
    Posts
    382

    Re: Convert vector<byte> to vector<short>?

    See attached for an approach that provides a byte-order-agnostic internal buffer, which just stores a current value as an array of bytes. The class also provides an interface for setting/getting bit-ranges. It also allows you to specify the byte-order of the integer that is passed to the setBits(), as well as the byte-order required for the value that we return from getBits() method.

    I'd love to improve this code to use insertion and extraction operators i.e operator>> and operator<< - while retaining the same functionality but my expertise is not there yet. A user here may already have an approach that uses insertion and extraction operators
    Attached Files Attached Files

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center