#ifndef __horrible_cast_h__ #define __horrible_cast_h__ //horrible_union is used by {safe|dangerous}_horrible_cast to copy one arbitrary type to another template union horrible_union { t_in in; t_out out; }; // dangerous_horrible_cast uses horrible_union to blindly copy one arbitrary type to another // // the data is zeroed out (via memset) before copying, in the case that he input type is smaller // than the output type template inline t_out dangerous_horrible_cast(t_in in) { // instance the union horrible_union data; // zero out the output part of the union (only if the input is actually smaller than the output) if ( sizeof(t_in) < sizeof(t_out) ) { memset(&data.out,0,sizeof(data.out)); } // copy the input into the union data.in = in; // return the output part out of the union return data.out; } // safe_horrible_cast is exactly like dangerous_horrible_cast, except it statically checks to make // certain that the output type (t_out) is at least large enough (in size) to store an instance of // the input type (t_in) // // note: if you use safe_horrible_cast to copy an instance of A to B, then you may safely use // dangerous_horrible_cast to copy an instance of B back to A. template inline t_out safe_horrible_cast(t_in in) { // statically (compile-time) test if t_out is at least as big as t_in typedef int ERROR___horrible_union_is_too_small_to_store_input_type[(sizeof(t_in) <= sizeof(t_out)) ? 1 : -1]; // now just do the regular horrible_cast return dangerous_horrible_cast(in); } #endif // __horrible_cast_h__