Skip to content

Instantly share code, notes, and snippets.

@evanzillians
Created January 8, 2013 17:33
Show Gist options
  • Save evanzillians/4485883 to your computer and use it in GitHub Desktop.
Save evanzillians/4485883 to your computer and use it in GitHub Desktop.
Dispatcher draft
#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