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
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
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";
}
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%2==0) ? byteVec[i]<<8 : byteVec[i]);
}
1 Attachment(s)
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