Here is a (bad) idea:
#include <utility>
template < typename InIter, typename OutIter >
std:
air<InIter, OutIter >
copy_n ( InIter from, OutIter where, std::size_t n ) {
for ( std::size_t i = 0; i < n; ++i ) {
*where = *from;
++ where;
++ from;
}
return ( std:
air< InIter, OutIter >( from, where ) );
}
template < typename InIter >
class binary_writer {
InIter where;
public:
binary_writer ( InIter from )
: where ( from )
{}
template < typename IntegerType >
binary_writer & operator<< ( IntegerType const & value ) {
unsigned char const * from =
static_cast < unsigned char const * >
( static_cast < void const * > ( &value ) );
where = copy_n( from, where, sizeof( IntegerType ) ).second;
return ( *this );
}
InIter position ( void ) const {
return ( where );
}
};
template < typename OutIter >
class binary_reader {
OutIter where;
public:
binary_reader ( OutIter from )
: where ( from )
{}
template < typename IntegerType >
binary_reader & operator>>( IntegerType & value ) {
unsigned char * from =
static_cast < unsigned char * >
( static_cast < void * > ( &value ) );
where = copy_n( where, from, sizeof( IntegerType ) ).first;
return ( *this );
}
OutIter position ( void ) const {
return ( where );
}
};
#include <vector>
#include <iostream>
#include <iterator>
int main ( void ) {
typedef std::vector< unsigned char > buffer_t;
typedef std::back_insert_iterator< buffer_t > out_iterator;
typedef buffer_t::const_iterator in_iterator;
int i = 1231414;
short j = 12341;
buffer_t the_buffer;
binary_writer< out_iterator > bw ( std::back_inserter( the_buffer ) );
bw << i << j;
int k;
short l;
binary_reader< in_iterator > br ( the_buffer.begin() );
br >> k >> l;
std::cout << "i = " << i << " k = " << k << "\n";
std::cout << "j = " << j << " l = " << l << "\n";
}
It is very clear that this code is in a state of sin: the casting testifies
to that. Drawbacks include, but may not be limited to:
(a) The code relies on binary representation and type sizes. So, if you use
this to transmit data through a network, both sides have to agree on that.
E.g., you could not use it to transmit ints from a 2-complement machine to a
signed magnitude machine.
(b) The code can be argued to invoke undefined behavior as it accesses an
object as an array of unsigned characters. This is usually fine for POD
types without padding, such as integer types of various sizes.
Generally, you should rather settle on a machine-independent protocol and
write conversion routines from and to the protocol.
Best,
Kai-Uwe