/*============================================================================= Copyright (c) 2006 Joel de Guzman Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(BOOST_OVERLOAD_06162006_2345) #define BOOST_OVERLOAD_06162006_2345 #include "is_compatible.hpp" #include #include #include namespace boost { template struct final_overload_function { struct final; static int const index = size; void operator()(final*) const {} }; template struct overload_function; template struct overload_function : Base { using Base::operator(); static int const index = Base::index - 1; R operator()() const { return get(static_cast(this)->functions)(); } }; template struct overload_function : Base { using Base::operator(); static int const index = Base::index - 1; R operator()(A0 a0) const { return get(static_cast(this)->functions)(a0); } }; template struct overload_function : Base { using Base::operator(); static int const index = Base::index - 1; R operator()(A0 a0, A1 a1) const { return get(static_cast(this)->functions)(a0, a1); } }; template struct overload_function : Base { using Base::operator(); static int const index = Base::index - 1; R operator()(A0 a0, A1 a1, A2 a2) const { return get(static_cast(this)->functions)(a0, a1, a2); } }; namespace detail { template struct overload_impl; template struct do_compose { typedef typename Seq::head_type head; typedef typename Seq::tail_type tail; typedef do_compose next; typedef typename next::type ov; typedef typename next::cons cons_tail; typedef overload_function type; typedef tuples::cons, cons_tail> cons; }; template struct do_compose { typedef typename Seq::head_type head; typedef final_overload_function final; typedef overload_function type; typedef tuples::tuple > cons; }; template struct compose_overload_base : do_compose< Seq, overload_impl, tuples::length::value, tuples::length::value > {}; template struct overload_impl : compose_overload_base::type { typedef compose_overload_base Base; typedef typename Base::cons functions_type; /* Find the correct signature among the registered * ones and assign the function/functor target */ template struct dummy { dummy(int){} }; // workaround SFINAE under gcc 3.4 template inline typename enable_if_c<(n == 0), int>::type do_set(F const&, dummy<0> = 0) { return -1; } template inline typename enable_if_c<(n != 0) && is_compatible::value, int>::type do_set(F const& f, dummy<1> = 0) { get(functions) = f; return size - n; } template inline typename enable_if_c<(n != 0) && !is_compatible::value, int>::type do_set(F const& f, dummy<2> = 0) { return do_set(f); } /* A couple of overloads to handle both pointers and plain types */ template inline int set(F const& f) { static int const size = tuples::length::value; return do_set(f); } template inline int set(F* f) { static int const size = tuples::length::value; return do_set(*f); } functions_type functions; }; } // detail /* Our public API, hide to the user we are using tuples */ template struct overload : detail::overload_impl < boost::tuple > {}; } #endif