Last active
December 22, 2015 04:28
-
-
Save nekko1119/6416763 to your computer and use it in GitHub Desktop.
良い感じにcast呼び分けてくれるcast考えてみた。絶対誰かやってる。
This file contains 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
#include <type_traits> | |
#include <utility> | |
#include <iostream> | |
struct static_cast_ | |
{ | |
template <class To, class From> | |
static To cast(From&& val) | |
{ | |
std::cout << "static_cast\n"; | |
return static_cast<To>(val); | |
} | |
}; | |
struct dynamic_cast_ | |
{ | |
template <class To, class From> | |
static To cast(From&& val) | |
{ | |
std::cout << "dynamic_cast\n"; | |
return dynamic_cast<To>(val); | |
} | |
}; | |
struct const_cast_ | |
{ | |
template <class To, class From> | |
static To cast(From&& val) | |
{ | |
std::cout << "const_cast\n"; | |
return const_cast<To>(val); | |
} | |
}; | |
struct reinterpret_cast_ | |
{ | |
template <class To, class From> | |
static To cast(From&& val) | |
{ | |
std::cout << "reinterpret_cast\n"; | |
return reinterpret_cast<To>(val); | |
} | |
}; | |
template <class To, class From> | |
To cast(From&& val) | |
{ | |
using type = | |
typename std::conditional< | |
std::is_base_of< | |
typename std::remove_pointer<typename std::remove_reference<From>::type>::type, | |
typename std::remove_pointer<typename std::remove_reference<To>::type>::type | |
>::value, | |
dynamic_cast_, | |
typename std::conditional< | |
((!std::is_const<typename std::remove_reference<To>::type>::value | |
&& std::is_const<typename std::remove_reference<From>::type>::value) | |
|| (!std::is_volatile<typename std::remove_reference<To>::type>::value | |
&& std::is_volatile<typename std::remove_reference<From>::type>::value)) | |
&& !std::is_convertible<typename std::remove_reference<From>::type, To>::value, | |
const_cast_, | |
typename std::conditional< | |
std::is_convertible<typename std::remove_reference<From>::type, To>::value, | |
static_cast_, | |
reinterpret_cast_ | |
>::type | |
>::type | |
>::type; | |
return type::template cast<To>(std::forward<From>(val)); | |
} | |
//test | |
template <class T> | |
inline T* addressof(T& value) | |
{ | |
return cast<T*>(&cast<char&>(cast<const volatile char&>(value))); | |
} | |
struct hoge | |
{ | |
void* operator&() const | |
{ | |
return nullptr; | |
} | |
}; | |
struct base{virtual ~base(){}}; | |
struct derived : base {}; | |
int main() | |
{ | |
{ | |
float f = 10.0f; | |
int i = cast<int>(f);//static_cast | |
} | |
{ | |
const int& a = 10; | |
int& b = cast<int&>(a);//const_cast | |
} | |
{ | |
derived d; | |
base* b = &d; | |
derived* d2 = cast<derived*>(b);//dynamic_cast | |
} | |
{ | |
double d = 3.14; | |
int* i = cast<int*>(&d);//reinterpret_cast | |
} | |
hoge h; | |
std::cout << addressof(h); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment