Last active
June 17, 2019 20:57
-
-
Save Sam-Belliveau/6479104011400c8bb42f0e953fabcf1f to your computer and use it in GitHub Desktop.
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
| #ifndef SAM_BELLIVEAUS_LAZY_CAST_LIBRARY | |
| #define SAM_BELLIVEAUS_LAZY_CAST_LIBRARY 1 | |
| #include <cstdint> | |
| #include <type_traits> | |
| namespace lc { | |
| namespace type { | |
| template<typename T> | |
| struct data | |
| { | |
| static constexpr bool valid = std::is_trivial<T>::value && std::is_trivially_copyable<T>::value; | |
| static constexpr std::size_t size = sizeof(T); | |
| using pointer_cast = const T*; | |
| using reference_type = const T&; | |
| }; | |
| template<typename T, std::size_t S> | |
| struct data<T[S]> | |
| { | |
| static constexpr bool valid = std::is_trivial<T>::value && std::is_trivially_copyable<T>::value; | |
| static constexpr std::size_t size = sizeof(T) * S; | |
| using pointer_cast = const T*; | |
| using pointer_type = const T*; | |
| }; | |
| template<typename T> | |
| struct data<T[]> | |
| { | |
| static constexpr bool valid = false; | |
| static constexpr std::size_t size = 0; | |
| }; | |
| template<typename T> | |
| struct data<T*> | |
| { | |
| static constexpr bool valid = false; | |
| static constexpr std::size_t size = 0; | |
| }; | |
| template<typename Out, typename In> | |
| static constexpr void test() | |
| { | |
| static_assert(data<In>::valid, | |
| "lazy_cast() -> Invalid Input Data Type!" | |
| ); | |
| static_assert(data<Out>::valid, | |
| "lazy_cast() -> Invalid Output Data Type!" | |
| ); | |
| static_assert(data<In>::size == data<Out>::size, | |
| "lazy_cast() -> Mismatch Of Type Sizes!" | |
| ); | |
| } | |
| } | |
| // Lazy Cast that returns Pointer | |
| template<typename Out, typename In> | |
| static constexpr auto lazy_cast(const In& input) -> typename type::data<Out>::pointer_type | |
| { | |
| type::test<Out, In>(); | |
| return reinterpret_cast<typename type::data<Out>::pointer_cast>(&input); | |
| } | |
| // Lazy Cast that returns Reference | |
| template<typename Out, typename In> | |
| static constexpr auto lazy_cast(const In& input) -> typename type::data<Out>::reference_type | |
| { | |
| type::test<Out, In>(); | |
| return *reinterpret_cast<typename type::data<Out>::pointer_cast>(&input); | |
| } | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment