Is there a better way to copy the contents of a std::deque
into a byte-array? It seems like there should be something in the STL for doing this.
// Generate byte-array to transmit
uint8_t * i2c_message = new uint8_t[_tx.size()];
if ( !i2c_message ) {
errno = ENOMEM;
::perror("ERROR: FirmataI2c::endTransmission - Failed to allocate memory!");
} else {
size_t i = 0;
// Load byte-array
for ( const auto & data_byte : _tx ) {
i2c_message[i++] = data_byte;
}
// Transmit data
_marshaller.sendSysex(firmata::I2C_REQUEST, _tx.size(), i2c_message);
_stream.flush();
delete[] i2c_message;
}
I'm looking for suggestions for either space or speed or both...
EDIT: It should be noted that
_marshaller.sendSysex()
cannot throw.
FOLLOW UP:
I thought it would be worth recapping everything, because the comments are pretty illuminating (except for the flame war). :-P
The answer to the question as asked...
Use std::copy
The bigger picture:
Instead of simply increasing the raw performance of the code, it was worth considering adding robustness and longevity to the code base.
I had overlooked RAII - Resource Acquisition is Initialization. By going in the other direction and taking a slight performance hit, I could get big gains in resiliency (as pointed out by @PaulMcKenzie and @WhozCraig). In fact, I could even insulate my code from changes in a dependency!
Final Solution:
In this case, I actually have access to (and the ability to change) the larger code base - often not the case. I reevaluated* the benefit I was gaining from using a std::deque
and I swapped the entire underlying container to a std::vector
. Thus saving the performance hit of container swapping, and gaining the benefits of contiguous data and RAII.
*I chose a std::deque
because I always have to push_front
two bytes to finalize my byte-array before sending. However, since it is always two bytes, I was able to pad the vector with two dummy bytes and replace them by random access - O(n) time.