Created
January 8, 2013 17:33
-
-
Save evanzillians/4485883 to your computer and use it in GitHub Desktop.
Dispatcher draft
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
#include <iostream> | |
#include <tuple> | |
#include <type_traits> | |
#include <vector> | |
class node_base; | |
template<typename C> | |
std::false_type has_begin_end_eval(...); | |
template<typename C> | |
std::true_type has_begin_end_eval( | |
typename std::enable_if< | |
std::is_same< | |
decltype(static_cast<typename C::iterator (C::*)() >(&C::begin)), | |
typename C::iterator (C::*)() | |
>::value && | |
std::is_same< | |
decltype(static_cast<typename C::iterator (C::*)() >(&C::end )), | |
typename C::iterator (C::*)() | |
>::value | |
>::type* | |
); | |
template<typename T> | |
struct has_begin_end : decltype(has_begin_end_eval<T>(0)) {}; | |
template<typename T> | |
struct is_node_base : std::integral_constant< | |
bool, | |
std::is_same <node_base, typename std::remove_cv<T>::type>::value || | |
std::is_base_of<node_base, typename std::remove_cv<T>::type>::value | |
> {}; | |
class node_base { | |
public: | |
virtual bool replace() { return true; }; | |
protected: | |
template<typename T > bool replace_impl(T *&t); | |
template<typename ...Ts > bool replace_impl(std::tuple<Ts... > &t); | |
template<typename T , typename std::enable_if< has_begin_end<T>::value>::type * = nullptr> bool replace_impl(T &t); | |
template<typename T , typename std::enable_if< is_node_base <T>::value>::type * = nullptr> bool replace_impl(T &t); | |
template<typename T , typename std::enable_if<!has_begin_end<T>::value && | |
!is_node_base <T>::value>::type * = nullptr> bool replace_impl(T &t); | |
template<std::size_t i, typename tuple_type> bool replace_impl_tuple(tuple_type &t, std::true_type ); | |
template<std::size_t i, typename tuple_type> bool replace_impl_tuple(tuple_type &t, std::false_type); | |
}; | |
template<typename T> | |
bool node_base::replace_impl(T *&t) { | |
std::cout << "Pointer" << std::endl; | |
return true; | |
} | |
template<typename ...Ts> | |
bool node_base::replace_impl(std::tuple<Ts...> &t) { | |
std::cout << "Tuple - begin" << std::endl; | |
replace_impl_tuple<0>( | |
t, | |
std::integral_constant< | |
bool, | |
0 != std::tuple_size<typename std::remove_reference<decltype(t)>::type>::value | |
>() | |
); | |
std::cout << "Tuple - end" << std::endl; | |
return true; | |
} | |
template<std::size_t i, typename tuple_type> | |
bool node_base::replace_impl_tuple(tuple_type &t, std::true_type) | |
{ | |
replace_impl(std::get<i>(t)); | |
replace_impl_tuple<i + 1>( | |
t, | |
std::integral_constant< | |
bool, | |
i + 1 != std::tuple_size<tuple_type>::value | |
>() | |
); | |
return true; | |
} | |
template<std::size_t i, typename tuple_type> | |
bool node_base::replace_impl_tuple(tuple_type &t, std::false_type) | |
{ | |
return true; | |
} | |
template< | |
typename T, | |
typename std::enable_if< | |
has_begin_end<T>::value | |
>::type *// = nullptr | |
> | |
bool node_base::replace_impl(T &t) { | |
std::cout << "Container" << std::endl; | |
return true; | |
} | |
template< | |
typename T, | |
typename std::enable_if< | |
is_node_base<T>::value | |
>::type *// = nullptr | |
> | |
bool node_base::replace_impl(T &t) { | |
std::cout << "Node&" << std::endl; | |
return true; | |
} | |
template< | |
typename T, | |
typename std::enable_if< | |
!has_begin_end<T>::value && | |
!is_node_base <T>::value | |
>::type *// = nullptr | |
> | |
bool node_base::replace_impl(T &t) { | |
std::cout << "Other" << std::endl; | |
return true; | |
} | |
class derived : node_base { | |
public: | |
virtual bool replace() override | |
{ | |
replace_impl(value ); | |
replace_impl(referred); | |
replace_impl(ints ); | |
replace_impl(tuple ); | |
return false; | |
} | |
private: | |
int value = 0; | |
node_base *referred = nullptr; | |
std::vector<int> ints; | |
std::tuple<int, float, node_base*> tuple = std::make_tuple(1, 1.0f, new node_base); | |
}; | |
int main() { | |
derived d; | |
d.replace(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment