I want to port a Qt C++11 function to standard C++11. The function has a QByteArray
parameter that accepts any kind of data (text, binary data, etc.) and calculates a hash from the data.
QByteArray
seems well suited because it can carry any kind of data and has a lot of functions that allow filling it from streams, devices, strings, etc. It even can wrap data without doing a deep copy using fromRawData()
.
Is there a standard C++11 solution that provides similar flexibility? Currently I tend to use good old void*
plus size.
Is there a standard C++11 solution that provides similar flexibility? Currently I tend to use good old void* plus size.
There's no standard C++11 solution that provides a container that can both manage its own memory or wrap memory managed by someone else.
You could simply copy the QByteArray
(it's a few files) and bundle it with your project, if licensing terms allow.
Otherwise, if you only intend to work on containers with contiguous storage for all elements, the const void*
and size_t
arguments make perfect sense, and will be most portable and adaptable. You can provide convenience overloads as needed. E.g.
HashType calculateHash(const void*, size_t);
template <typename T> HashType calculateHash(const T& container) {
static_assert(sizeof(typename T::value_type) == 1, "value_type must be byte-sized");
assert(&container[container.size()-1] == &container[0]+container.size());
return calculateHash(&container[0], container.size());
}
To support any container, even those with non-contiguous storage, the base calculateHash
can take a range and offer an overload for hashing an entire container.
template <typename I>
HashType calculateHash(I start, I const end) {
HashType hash;
for (; start != end; ++start)
hash.update(*start);
return hash;
}
template <typename C>
HashType calculateHash(const C& container) {
using std::begin;
using std::end;
return calculateHash(begin(container), end(container));
}
I do not know such kind of standard container that has the same complex functionality what QByteArray has but I would start with std::vector< char >
and would implement a wrapper around that with the missing and necessary functions.
std::vector
has high flexibility, you can access each element in constant time and you can easily convert it to std::string (for example Converting a vector to string).
If the insert operation is more important maybe you can try std::list< char >
. Mainly this is linked list implementation.
Based on the comment from Jesper Juhl: using uint8_t
as template argument would describe the real the byte array behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With