Created
May 30, 2018 15:35
-
-
Save ArXen42/f363f8f808596c1737686d88c24f241c to your computer and use it in GitHub Desktop.
horrible_cast.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //From https://github.com/pbhogan/Signals | |
| // horrible_cast< > | |
| // This is truly evil. It completely subverts C++'s type system, allowing you | |
| // to cast from any class to any other class. Technically, using a union | |
| // to perform the cast is undefined behaviour (even in C). But we can see if | |
| // it is OK by checking that the union is the same size as each of its members. | |
| // horrible_cast<> should only be used for compiler-specific workarounds. | |
| // Usage is identical to reinterpret_cast<>. | |
| // This union is declared outside the horrible_cast because BCC 5.5.1 | |
| // can't inline a function with a nested class, and gives a warning. | |
| template<class OutputClass, class InputClass> | |
| union horrible_union | |
| { | |
| OutputClass out; | |
| InputClass in; | |
| }; | |
| template<class OutputClass, class InputClass> | |
| inline OutputClass horrible_cast(const InputClass input) | |
| { | |
| horrible_union<OutputClass, InputClass> u; | |
| // Cause a compile-time error if in, out and u are not the same size. | |
| // If the compile fails here, it means the compiler has peculiar | |
| // unions which would prevent the cast from working. | |
| typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass) == sizeof(u) | |
| && sizeof(InputClass) == sizeof(OutputClass) ? 1 : -1]; | |
| u.in = input; | |
| return u.out; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment