#include <cstring>
#include <iostream>
#include <type_traits>
// TODO: static_assert to detect alignment errors.
template < typename T, typename U>
struct binary_concat_t {
enum { total_size = sizeof ( T) + sizeof ( U) } ;
binary_concat_t( const T & t, const U & u) : t( t) , u( u) { }
const char * data( ) const { return reinterpret_cast < const char * > ( this ) ; }
T t;
U u;
} ;
template < typename T, typename U>
binary_concat_t< T, U> binary_concat( const T & t, const U & u) {
static_assert( std:: is_pod < binary_concat_t< T, U>> :: value , "Type must be POD!" ) ;
return binary_concat_t< T, U> ( t, u) ;
}
template < typename T, typename U, typename V>
binary_concat_t< binary_concat_t< T, U> , V> binary_concat( const T & t, const U & u, const V & v) {
return binary_concat( binary_concat( t, u) , v) ;
}
struct IPv4Header {
char data[ 17 ] ;
} ;
struct TCPHeader {
char data[ 20 ] ;
} ;
struct HTTPHeader {
char data[ 23 ] ;
} ;
int main( ) {
IPv4Header ipv4;
TCPHeader tcp;
HTTPHeader http;
auto data = binary_concat( ipv4, tcp, http) ;
std:: cout << "sizeof(IPv4Header) = " << sizeof ( IPv4Header) << std:: endl ;
std:: cout << "sizeof(TCPHeader) = " << sizeof ( TCPHeader) << std:: endl ;
std:: cout << "sizeof(HTTPHeader) = " << sizeof ( HTTPHeader) << std:: endl ;
std:: cout << "sizeof(data) = " << sizeof ( data) << std:: endl ;
}
I2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKLy8gVE9ETzogc3RhdGljX2Fzc2VydCB0byBkZXRlY3QgYWxpZ25tZW50IGVycm9ycy4KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CnN0cnVjdCBiaW5hcnlfY29uY2F0X3QgewogICAgZW51bSB7IHRvdGFsX3NpemUgPSBzaXplb2YoVCkgKyBzaXplb2YoVSkgfTsKCiAgICBiaW5hcnlfY29uY2F0X3QoY29uc3QgVCAmIHQsIGNvbnN0IFUgJiB1KSA6IHQodCksIHUodSkge30KCiAgICBjb25zdCBjaGFyICogZGF0YSgpIGNvbnN0IHsgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHRoaXMpOyB9CiAgICAKICAgIFQgdDsKICAgIFUgdTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CmJpbmFyeV9jb25jYXRfdDxULCBVPiBiaW5hcnlfY29uY2F0KGNvbnN0IFQgJiB0LCBjb25zdCBVICYgdSkgewogICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX3BvZDxiaW5hcnlfY29uY2F0X3Q8VCwgVT4+Ojp2YWx1ZSwgIlR5cGUgbXVzdCBiZSBQT0QhIik7CiAgICByZXR1cm4gYmluYXJ5X2NvbmNhdF90PFQsIFU+KHQsIHUpOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBVLCB0eXBlbmFtZSBWPgpiaW5hcnlfY29uY2F0X3Q8YmluYXJ5X2NvbmNhdF90PFQsIFU+LCBWPiBiaW5hcnlfY29uY2F0KGNvbnN0IFQgJiB0LCBjb25zdCBVICYgdSwgY29uc3QgViAmIHYpIHsKICAgIHJldHVybiBiaW5hcnlfY29uY2F0KGJpbmFyeV9jb25jYXQodCwgdSksIHYpOwp9CgpzdHJ1Y3QgSVB2NEhlYWRlciB7CiAgICBjaGFyIGRhdGFbMTddOwp9OwoKc3RydWN0IFRDUEhlYWRlciB7CiAgICBjaGFyIGRhdGFbMjBdOwp9OwoKc3RydWN0IEhUVFBIZWFkZXIgewogICAgY2hhciBkYXRhWzIzXTsKfTsKCmludCBtYWluKCkgewogICAgSVB2NEhlYWRlciBpcHY0OwogICAgVENQSGVhZGVyIHRjcDsKICAgIEhUVFBIZWFkZXIgaHR0cDsKICAgIGF1dG8gZGF0YSA9IGJpbmFyeV9jb25jYXQoaXB2NCwgdGNwLCBodHRwKTsKCiAgICBzdGQ6OmNvdXQgPDwgInNpemVvZihJUHY0SGVhZGVyKSA9ICIgPDwgc2l6ZW9mKElQdjRIZWFkZXIpIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAic2l6ZW9mKFRDUEhlYWRlcikgPSAiIDw8IHNpemVvZihUQ1BIZWFkZXIpIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAic2l6ZW9mKEhUVFBIZWFkZXIpID0gIiA8PCBzaXplb2YoSFRUUEhlYWRlcikgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8ICJzaXplb2YoZGF0YSkgPSAiIDw8IHNpemVvZihkYXRhKSA8PCBzdGQ6OmVuZGw7Cn0=
compilation info
prog.cpp: In function 'binary_concat_t<T, U> binary_concat(const T&, const U&) [with T = IPv4Header, U = TCPHeader]':
prog.cpp:27:48: instantiated from 'binary_concat_t<binary_concat_t<T, U>, V> binary_concat(const T&, const U&, const V&) [with T = IPv4Header, U = TCPHeader, V = HTTPHeader]'
prog.cpp:46:46: instantiated from here
prog.cpp:21:5: error: static assertion failed: "Type must be POD!"
prog.cpp: In function 'binary_concat_t<T, U> binary_concat(const T&, const U&) [with T = binary_concat_t<IPv4Header, TCPHeader>, U = HTTPHeader]':
prog.cpp:27:48: instantiated from 'binary_concat_t<binary_concat_t<T, U>, V> binary_concat(const T&, const U&, const V&) [with T = IPv4Header, U = TCPHeader, V = HTTPHeader]'
prog.cpp:46:46: instantiated from here
prog.cpp:21:5: error: static assertion failed: "Type must be POD!"
stdout