// ----------------------------------------------------------------------------- // mpl // ----------------------------------------------------------------------------- namespace mpl { // bool_, true_, false_ template struct bool_ { static const bool value = C; typedef bool_ type; }; typedef bool_ true_; typedef bool_ false_; // if_ template struct if_helper { typedef T2 type; }; template struct if_helper { typedef T1 type; }; template struct if_ { typedef typename if_helper::type type; }; // eval_if template struct eval_if { typedef typename if_::type::type type; }; // pair template struct pair { typedef pair type; typedef T1 first; typedef T2 second; }; // inherit template struct inherit { struct inherit_helper : public T1, public T2 { typedef inherit_helper type; }; typedef inherit_helper type; }; // identity template struct identity { typedef X type; }; // void_, is_void struct void_ { typedef void_ type; }; template struct is_void { typedef false_ type; }; template <> struct is_void { typedef true_ type; }; // list template < typename T1 = void_, typename T2 = void_, typename T3 = void_, typename T4 = void_, typename T5 = void_, typename T6 = void_, typename T7 = void_, typename T8 = void_, typename T9 = void_, typename T10 = void_, typename T11 = void_, typename T12 = void_, typename T13 = void_, typename T14 = void_, typename T15 = void_, typename T16 = void_, typename T17 = void_, typename T18 = void_, typename T19 = void_, typename T20 = void_, typename T21 = void_, typename T22 = void_, typename T23 = void_, typename T24 = void_, typename T25 = void_, typename T26 = void_, typename T27 = void_, typename T28 = void_, typename T29 = void_, typename T30 = void_, typename T31 = void_, typename T32 = void_ > struct list { typedef list type; typedef T1 head; typedef list< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32 > tail; }; // push_front template struct push_front; template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17, typename T18, typename T19, typename T20, typename T21, typename T22, typename T23, typename T24, typename T25, typename T26, typename T27, typename T28, typename T29, typename T30, typename T31, typename T32, typename T > struct push_front, T> { typedef list< T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31 > type; }; // reverse template struct reverse_helper { typedef typename eval_if< typename is_void::type, ReversedList, reverse_helper< typename List::tail, typename push_front::type > >::type type; }; template struct reverse { typedef typename reverse_helper >::type type; }; // for_each template struct for_each_helper { template static void invoke(F) {} }; template <> struct for_each_helper { template static void invoke(F f) { f(typename List::head()); for_each_helper< is_void::type::value >::template invoke(f); } }; template void for_each(F f) { for_each_helper< is_void::type::value >::template invoke(f); } // joint_view template struct joint_view_helper { typedef typename eval_if< typename is_void::type, List2, joint_view_helper< typename List1::tail, typename push_front::type> >::type type; }; template struct joint_view { typedef typename joint_view_helper< typename reverse::type, List2 >::type type; }; // transform template < typename List, typename TransformedList, template class Operation > struct transform_helper { typedef typename eval_if< typename is_void::type, TransformedList, transform_helper< typename List::tail, typename push_front< TransformedList, typename Operation::type >::type, Operation > >::type type; }; template class Operation> struct transform { typedef typename transform_helper< typename reverse::type, list<>, Operation >::type type; }; // product_view template < typename T, typename List, typename ResultList, template class Operation > struct product_view_helper_3 { typedef typename eval_if< typename is_void::type, ResultList, product_view_helper_3< T, typename List::tail, typename push_front< ResultList, typename Operation::type >::type, Operation > >::type type; }; template < typename T, typename List, template class Operation > struct product_view_helper_2 { typedef typename product_view_helper_3< T, typename reverse::type, list<>, Operation >::type type; }; template < typename List1, typename List2, typename ProductList, template class Operation > struct product_view_helper_1 { typedef typename eval_if< typename is_void::type, ProductList, product_view_helper_1< typename List1::tail, List2, typename joint_view< typename product_view_helper_2< typename List1::head, List2, Operation >::type, ProductList >::type, Operation > >::type type; }; template < typename List1, typename List2, template class Operation = pair > struct product_view { typedef typename product_view_helper_1< typename reverse::type, List2, list<>, Operation >::type type; }; // inherit_linearly template struct inherit_linearly_helper { typedef typename eval_if< typename is_void::type, Base, inherit_linearly_helper< typename List::tail, typename inherit::type > >::type type; }; template struct inherit_linearly { typedef typename inherit_linearly_helper< typename reverse::type, void_ >::type type; }; } // namespace mpl // ----------------------------------------------------------------------------- // debugging // ----------------------------------------------------------------------------- #include #include #include #ifdef __GNUC__ # include #endif template void print_type(std::ostream& ostream) { #if defined (__GNUC__) ostream << abi::__cxa_demangle(typeid(T).name(), 0, 0, 0); #else ostream << typeid(T).name(); #endif } struct print_list_helper { print_list_helper(std::ostream& ostream, const std::string& separator) : ostream_(ostream), separator_(separator) {} template void operator()(T) { print_type(ostream_); ostream_ << separator_; } std::ostream& ostream_; std::string separator_; }; template void print_list(std::ostream& ostream, const std::string& separator) { mpl::for_each(print_list_helper(ostream, separator)); } // ----------------------------------------------------------------------------- // main program // ----------------------------------------------------------------------------- #include #include #include #include // types typedef std::tr1::uint8_t uint8; typedef std::tr1::uint16_t uint16; typedef std::tr1::uint32_t uint32; typedef std::tr1::int8_t int8; typedef std::tr1::int16_t int16; typedef std::tr1::int32_t int32; typedef float float32; typedef double float64; // scalar_types // scalar types typedef mpl::list< uint8, uint16, uint32, int8, int16, int32, float32, float64 > scalar_types; // scalar_type_callback // callback for scalar types template void scalar_type_callback() { #if defined (__GNUC__) std::cout << __PRETTY_FUNCTION__ << "\n"; #else std::cout << __FUNCTION__ << "\n"; #endif } // size_types // size types typedef mpl::list size_types; // list_types // list types // a list type is a combination of a size type and a scalar type template struct list_type { typedef SizeType size_type; typedef ScalarType scalar_type; typedef list_type type; }; typedef mpl::product_view::type list_types; // list_type_callback // callback for list types template void list_type_callback() { #if defined (__GNUC__) std::cout << __PRETTY_FUNCTION__ << "\n"; #else std::cout << __FUNCTION__ << "\n"; #endif } // scalar_type_callbacks_type // scalar_type_callbacks_type contains a callback for each scalar type template struct scalar_type_callbacks_callback { typedef scalar_type_callbacks_callback type; typedef std::tr1::function callback_type; callback_type callback; }; template inline typename scalar_type_callbacks_callback::callback_type& get(scalar_type_callbacks_callback& callback) { return callback.callback; } typedef mpl::inherit_linearly< mpl::transform::type >::type scalar_type_callbacks_type; // list_type_callbacks_type // list_type_callbacks_type contains a callback for each list type template struct list_type_callbacks_callback { typedef list_type_callbacks_callback type; typedef std::tr1::function callback_type; callback_type callback; }; template inline typename list_type_callbacks_callback::callback_type& get(list_type_callbacks_callback& callback) { return callback.callback; } template struct make_list_type_callbacks_callback { typedef make_list_type_callbacks_callback type; }; template struct make_list_type_callbacks_callback > { typedef list_type_callbacks_callback type; }; typedef mpl::inherit_linearly< mpl::transform::type >::type list_type_callbacks_type; // main int main (int argc, char * const argv[]) { std::cout << "scalar types:\n"; print_list(std::cout, "\n"); std::cout << "\n"; std::cout << "size types:\n"; print_list(std::cout, "\n"); std::cout << "\n"; std::cout << "list types:\n"; print_list(std::cout, "\n"); std::cout << "\n"; std::cout << "scalar_type_callbacks_type: "; print_type(std::cout); std::cout << "\n"; scalar_type_callbacks_type scalar_type_callbacks; get< uint8>(scalar_type_callbacks) = scalar_type_callback; get< uint16>(scalar_type_callbacks) = scalar_type_callback; get< uint32>(scalar_type_callbacks) = scalar_type_callback; get< int8>(scalar_type_callbacks) = scalar_type_callback; get< int16>(scalar_type_callbacks) = scalar_type_callback; get< int32>(scalar_type_callbacks) = scalar_type_callback; get(scalar_type_callbacks) = scalar_type_callback; get(scalar_type_callbacks) = scalar_type_callback; get< uint8>(scalar_type_callbacks)(); get< uint16>(scalar_type_callbacks)(); get< uint32>(scalar_type_callbacks)(); get< int8>(scalar_type_callbacks)(); get< int16>(scalar_type_callbacks)(); get< int32>(scalar_type_callbacks)(); get(scalar_type_callbacks)(); get(scalar_type_callbacks)(); std::cout << "list_type_callbacks_type: "; print_type(std::cout); std::cout << "\n"; list_type_callbacks_type list_type_callbacks; get< uint8, uint8>(list_type_callbacks) = list_type_callback< uint8, uint8>; get< uint8, uint16>(list_type_callbacks) = list_type_callback< uint8, uint16>; get< uint8, uint32>(list_type_callbacks) = list_type_callback< uint8, uint32>; get< uint8, int8>(list_type_callbacks) = list_type_callback< uint8, int8>; get< uint8, int16>(list_type_callbacks) = list_type_callback< uint8, int16>; get< uint8, int32>(list_type_callbacks) = list_type_callback< uint8, int32>; get< uint8, float32>(list_type_callbacks) = list_type_callback< uint8, float32>; get< uint8, float64>(list_type_callbacks) = list_type_callback< uint8, float64>; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get(list_type_callbacks) = list_type_callback; get< uint8, uint8>(list_type_callbacks)(); get< uint8, uint16>(list_type_callbacks)(); get< uint8, uint32>(list_type_callbacks)(); get< uint8, int8>(list_type_callbacks)(); get< uint8, int16>(list_type_callbacks)(); get< uint8, int32>(list_type_callbacks)(); get< uint8, float32>(list_type_callbacks)(); get< uint8, float64>(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); get(list_type_callbacks)(); }