#ifndef MultimethodH #define MultimethodH /*--------------------------------------------------------------------------- Multimethod.hpp --------------------------------------------------------------------------- Copyright (C) 2009/01 - 2009 Nowake nowake@fircewinds.net ----------------------------------------------------------------------------*/ #include #include #include #include #include namespace Loki { std::size_t hash_value(const TypeInfo& value) { boost::hash hasher; return hasher(&(value.Get())); } } ////////////////////////////////////////////////////////////////////////////// // multi method executor ////////////////////////////////////////////////////////////////////////////// struct Multimethod { Multimethod() {}; public: ////////////////////////////////////////////////////////////////////// template struct ArgumentTraits; template struct ApplyTraits { template R operator()(A00& a00) { return a00(); }; template R operator()(A00& a00, A01& a01) { return a00(a01); }; template R operator()(A00& a00, A01& a01, A02& a02) { return a00(a01, a02); }; template R operator()(A00& a00, A01& a01, A02& a02, A03& a03) { return a00(a01, a02, a03); }; }; template<> struct ApplyTraits { template void operator()(A00& a00) { a00(); }; template void operator()(A00& a00, A01& a01) { a00(a01); }; template void operator()(A00& a00, A01& a01, A02& a02) { a00(a01, a02); }; template void operator()(A00& a00, A01& a01, A02& a02, A03& a03) { a00(a01, a02, a03); }; }; /////////////////////////////////////////////////////////////////////////// template struct ReturnEmptyValue { template R operator()(A00& a00) { a00(); return R(); }; template R operator()(A00& a00, A01& a01) { a00(a01); return R(); }; template R operator()(A00& a00, A01& a01, A02& a02) { a00(a01, a02); return R(); }; template R operator()(A00& a00, A01& a01, A02& a02, A03& a03) { a00(a01, a02, a03); return R(); }; }; public: ////////////////////////////////////////////////////////////////////// class BadMultimethod : public std::bad_cast { public: virtual const char * what() const throw() { return "Bad Multimethod apply: no entried argument set."; }; }; private: ///////////////////////////////////////////////////////////////////// template class map { public: typedef map item_type; typedef std::map map_type; //typedef boost::unordered_map map_type; item_type& find(const T& t) { std::pair r(d_.insert(make_pair(t, item_type()))); return r.first->second; } private: map_type d_; }; template struct map { public: typedef R item_type; typedef std::map map_type; //typedef boost::unordered_map map_type; item_type& find(const T& t) { std::pair r(d_.insert(make_pair(t, item_type()))); return r.first->second; } private: map_type d_; }; template static R& find(const T& t00) { static map m; return m.find(t00); }; template static R& find(const T& t00, const T& t01) { static map m; return m.find(t00).find(t01); }; template static R& find(const T& t00, const T& t01, const T& t02) { static map m; return m.find(t00).find(t01).find(t02); }; template static R& find(const T& t00, const T& t01, const T& t02, const T& t03) { static map m; return m.find(t00).find(t01).find(t02).find(t03); }; private://////////////////////////////////////////////////////////////////////// template struct Apply00 { static A& apply() { static A a; return a; }; static R trampoline(HHH& a00) { return apply()(ArgumentTraits::cast(a00)); }; }; public: template static bool entry() { return entry(ApplyTraits()); }; template static bool entry(A apply) { typedef R (*T00)(HHH&); find(ArgumentTraits::id()) = &Apply00::trampoline; Apply00::apply() = apply; return true; }; template static R apply(HHH& a00) { typedef R (*T)(HHH&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00); }; private://////////////////////////////////////////////////////////////////////// template struct Apply01 { static A& apply() { static A a; return a; }; static R trampoline(HHH& a00, HHH& a01) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01)); }; static R trampoline(A00& a00, HHH& a01) { return apply()(a00, ArgumentTraits::cast(a01)); }; static R trampoline(HHH& a00, A01& a01) { return apply()(ArgumentTraits::cast(a00), a01); }; }; public: template static bool entry() { return entry(ApplyTraits()); }; template static bool entry(A apply) { typedef R (*T00)(HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply01::trampoline; typedef R (*T01)(A00&, HHH&); find(ArgumentTraits::id()) = &Apply01::trampoline; typedef R (*T02)(HHH&, A01&); find(ArgumentTraits::id()) = &Apply01::trampoline; Apply01::apply() = apply; return true; }; template static R apply(T00& a00, T01& a01) { typedef R (*T)(T00&, T01&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01); }; template static R apply(HHH& a00, HHH& a01) { typedef R (*T)(HHH&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01); }; template static R apply(T00& a00, HHH& a01, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01); }; template static R apply(HHH& a00, T00& a01, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01); }; template static R apply(const T00& a00, HHH& a01, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01); }; template static R apply(HHH& a00, const T00& a01, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01); }; private: /////////////////////////////////////////////////////////////////////// template struct Apply02 { static A& apply() { static A a; return a; }; static R trampoline(HHH& a00, HHH& a01, HHH& a02) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), ArgumentTraits::cast(a02)); }; static R trampoline(A00& a00, HHH& a01, HHH& a02) { return apply()(a00, ArgumentTraits::cast(a01), ArgumentTraits::cast(a02)); }; static R trampoline(HHH& a00, A01& a01, HHH& a02) { return apply()(ArgumentTraits::cast(a00), a01, ArgumentTraits::cast(a02)); }; static R trampoline(HHH& a00, HHH& a01, A02& a02) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), a02); }; static R trampoline(HHH& a00, A01& a01, A02& a02) { return apply()(ArgumentTraits::cast(a00), a01, a02); }; static R trampoline(A00& a00, HHH& a01, A02& a02) { return apply()(a00, ArgumentTraits::cast(a01), a02); }; static R trampoline(A00& a00, A01& a01, HHH& a02) { return apply()(a00, a01, ArgumentTraits::cast(a02)); }; }; public: template static bool entry() { return entry(ApplyTraits()); }; template static bool entry(A apply) { typedef R (*T00)(HHH&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T01)(A00&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T02)(HHH&, A01&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T03)(HHH&, HHH&, A02&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T04)(HHH&, A01&, A02&); find(ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T05)(A00&, HHH&, A02&); find(ArgumentTraits::id()) = &Apply02::trampoline; typedef R (*T06)(A00&, A01&, HHH&); find(ArgumentTraits::id()) = &Apply02::trampoline; Apply02::apply() = apply; return true; }; template static R apply(HHH& a00, HHH& a01, HHH& a02) { typedef R (*T)(HHH&, HHH&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(T00& a00, HHH& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, T00& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(ma02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, HHH& a01, T00& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, T00& a01, T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, T01&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(T00& a00, HHH& a01, T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, T01&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(T00& a00, T01& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, HHH&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(const T00& a00, HHH& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, const T00& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(ma02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, HHH& a01, const T00& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, const T00); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, const T00& a01, T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, T01&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, T00& a01, const T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, const T01&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(HHH& a00, const T00& a01, const T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, const T01&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(const T00& a00, HHH& a01, T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, T01&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(T00& a00, HHH& a01, const T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, const T01&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(const T00& a00, HHH& a01, const T01& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, const T01&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(const T00& a00, T01& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, HHH&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(T00& a00, const T01& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, HHH&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; template static R apply(const T00& a00, const T01& a01, HHH& a02, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, HHH&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02); }; private: ////////////////////////////////////////////////////////////////////// template struct Apply03 { static A& apply() { static A a; return a; }; static R trampoline(HHH& a00, HHH& a01, HHH& a02, HHH& a03) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), ArgumentTraits::cast(a02), ArgumentTraits::cast(a03)); }; static R trampoline(A00& a00, HHH& a01, HHH& a02, HHH& a03) { return apply()(a00, ArgumentTraits::cast(a01), ArgumentTraits::cast(a02), ArgumentTraits::cast(a03)); }; static R trampoline(HHH& a00, A01& a01, HHH& a02, HHH& a03) { return apply()(ArgumentTraits::cast(a00), a01, ArgumentTraits::cast(a02), ArgumentTraits::cast(a03)); }; static R trampoline(HHH& a00, HHH& a01, A02& a02, HHH& a03) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), a02, ArgumentTraits::cast(a03)); }; static R trampoline(HHH& a00, HHH& a01, HHH& a02, A03& a03) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), ArgumentTraits::cast(a02), a03); }; static R trampoline(A00& a00, A01& a01, HHH& a02, HHH& a03) { return apply()(a00, a01, ArgumentTraits::cast(a02), ArgumentTraits::cast(a03)); }; static R trampoline(A00& a00, HHH& a01, A02& a02, HHH& a03) { return apply()(a00, ArgumentTraits::cast(a01), a02, ArgumentTraits::cast(a03)); }; static R trampoline(A00& a00, HHH& a01, HHH& a02, A03& a03) { return apply()(a00, ArgumentTraits::cast(a01), ArgumentTraits::cast(a02), a03); }; static R trampoline(HHH& a00, A01& a01, A02& a02, HHH& a03) { return apply()(ArgumentTraits::cast(a00), a01, a02, ArgumentTraits::cast(a03)); }; static R trampoline(HHH& a00, A01& a01, HHH& a02, A03& a03) { return apply()(ArgumentTraits::cast(a00), a01, ArgumentTraits::cast(a02), a03); }; static R trampoline(HHH& a00, HHH& a01, A02& a02, A03& a03) { return apply()(ArgumentTraits::cast(a00), ArgumentTraits::cast(a01), a02, a03); }; static R trampoline(HHH& a00, A01& a01, A02& a02, A03& a03) { return apply()(ArgumentTraits::cast(a00), a01, a02, a03); }; static R trampoline(A00& a00, HHH& a01, A02& a02, A03& a03) { return apply()(a00, ArgumentTraits::cast(a01), a02, a03); }; static R trampoline(A00& a00, A01& a01, HHH& a02, A03& a03) { return apply()(a00, a01, ArgumentTraits::cast(a02), a03); }; static R trampoline(A00& a00, A01& a01, A02& a02, HHH& a03) { return apply()(a00, a01, a02, ArgumentTraits::cast(a03)); }; }; public: template static bool entry() { return entry(ApplyTraits()); }; template static bool entry(A apply) { typedef R (*T00)(HHH&, HHH&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T01)(A00&, HHH&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T02)(HHH&, A01&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T03)(HHH&, HHH&, A02&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T04)(HHH&, HHH&, HHH&, A03&); find(ArgumentTraits::id(), ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T05)(A00&, A01&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T06)(A00&, HHH&, A02&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T07)(A00&, A01&, HHH&, HHH&); find(ArgumentTraits::id(), ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T08)(HHH&, A01&, A02&, A03&); find(ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T09)(A00&, HHH&, A02&, A03&); find(ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T10)(A00&, A01&, HHH&, A03&); find(ArgumentTraits::id()) = &Apply03::trampoline; typedef R (*T11)(A00&, A01&, A02&, HHH&); find(ArgumentTraits::id()) = &Apply03::trampoline; Apply03::apply() = apply; return true; }; template static R apply(HHH& a00, HHH& a01, HHH& a02, HHH& a03) { typedef R (*T)(HHH&, HHH&, HHH&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, HHH&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, HHH&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, HHH&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, HHH&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, T00& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, T00&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, const T00& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, const T00&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, HHH& a02, T00& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, HHH&, T00&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, HHH& a02, const T00& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, HHH&, const T00&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, HHH&, HHH&); T t(find(ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, HHH&, HHH&); T t(find(ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, const T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, HHH&, HHH&); T t(find(ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, const T01& a01, HHH& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, HHH&, HHH&); T t(find(ArgumentTraits::id(a02), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, T01&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, T01&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, const T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, const T01&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, const T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, const T01&, HHH&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, HHH& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, HHH&, T01&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, HHH& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, HHH&, T01&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, HHH& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, HHH&, const T01&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, HHH& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, HHH&, const T01&); T t(find(ArgumentTraits::id(a01), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, T01&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, T01&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, const T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, const T01&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, const T01& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, const T01&, HHH&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, HHH& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, HHH&, T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, HHH& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, HHH&, T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, HHH& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, HHH&, const T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, HHH& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, HHH&, const T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, T00& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, T00&, T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, const T00& a02, T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, const T00&, T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, T00& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, T00&, const T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, HHH& a01, const T00& a02, const T01& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, HHH&, const T00&, const T01&); T t(find(ArgumentTraits::id(a00), ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, T01&, T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, T01&, T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, const T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, const T01&, T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, T01&, const T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, const T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, const T01&, T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, T01&, const T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, T00& a01, const T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, T00&, const T01&, const T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(HHH& a00, const T00& a01, const T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(HHH&, const T00&, const T01&, const T02&); T t(find(ArgumentTraits::id(a00))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, T01&, T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, T01&, T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, const T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, const T01&, T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, HHH& a01, T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, HHH&, T01&, const T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, const T01& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, const T01&, T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, T01&, const T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, HHH& a01, const T01& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, HHH&, const T01&, const T02&); T t(find(ArgumentTraits::id(a01))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, T01& a01, HHH& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, HHH&, T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, T01& a01, HHH& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, HHH&, T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, const T01& a01, HHH& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, HHH&, T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, HHH&, const T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, const T01& a01, HHH& a02, T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, HHH&, T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, HHH&, const T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, const T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, HHH&, const T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, const T01& a01, HHH& a02, const T02& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, HHH&, const T02&); T t(find(ArgumentTraits::id(a02))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, T01& a01, T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, T01& a01, T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, const T01& a01, T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, T01&, const T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, const T01& a01, T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, T01&, const T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(T00& a00, const T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(T00&, const T01&, const T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; template static R apply(const T00& a00, const T01& a01, const T02& a02, HHH& a03, typename ArgumentTraits::type* = 0) { typedef R (*T)(const T00&, const T01&, const T02&, HHH&); T t(find(ArgumentTraits::id(a03))); if (!t) throw BadMultimethod(); return t(a00, a01, a02, a03); }; }; ////////////////////////////////////////////////////////////////////////////// template<> struct Multimethod::ArgumentTraits { typedef boost::any type; static Loki::TypeInfo id(type& target) { return Loki::TypeInfo(target.type()); }; template static Loki::TypeInfo id() { static Loki::TypeInfo r(Loki::TypeInfo((type(target_t()).type()))); return r; }; template static type_t cast(type& operand) { return boost::any_cast::type&>(operand); }; }; #endif