Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Last active December 22, 2015 04:28
Show Gist options
  • Save nekko1119/6416763 to your computer and use it in GitHub Desktop.
Save nekko1119/6416763 to your computer and use it in GitHub Desktop.
良い感じにcast呼び分けてくれるcast考えてみた。絶対誰かやってる。
#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