// Fake typeof implementation. Yes, we're using typeof, but the // amount of manual registration needed is carefully limited. We will // use Alexander Nasonov's implementation, which doesn't require users // to conjure up unique primes. #include #define typeof(x) typename typeof_::type template struct typeof_; template struct template_typeof_result { static T t; enum { x = n*sizeof(typeof_lookup_(t)) }; typedef char type[x]; }; // n must be a unique prime #define TYPEOF_REGISTER_CLASS(ns,x,n) \ } \ template \ char(& \ typeof_lookup_(T) \ )[n]; \ \ template \ struct typeof_< \ m \ , typename boost::enable_if_c<(m == n)>::type \ > \ { \ typedef ns::x type; \ }; \ namespace ns { // n must be a unique prime #define TYPEOF_REGISTER_TEMPLATE(ns,x,n) \ } \ template \ typename template_typeof_result::type \ typeof_lookup_(ns::x); \ \ template \ struct typeof_< \ m \ , typename boost::disable_if_c<(m == n)>::type \ , typename boost::enable_if_c<(m%n == 0)>::type \ > \ { \ typedef ns::x::type> type; \ }; \ namespace ns { \ // ----------------- namespace algorithm { template struct traversal_category { typedef typename Range::traversal_category type; }; struct copy_tag {}; // identify the copy algorithm TYPEOF_REGISTER_CLASS(algorithm,copy_tag,3) namespace detail { // Compute the result of invoking any given algorithm template struct dispatch { typedef typename traversal_category::type cat1; typedef typename traversal_category::type cat2; // lookup_implementation uses ADL on category tags to look up an // implementation for this algorithm object. typedef typeof( lookup_implementation(AlgorithmID(), cat1(), cat2()) ) implementation; typedef typename implementation::template result_type::type result; }; } // // The copy algorithm dispatcher // template typename detail::dispatch::result copy(Range1 const& src, Range2& dst) { return detail::dispatch::implementation ::execute(src,dst); } // Other algorithm dispatchers here... } // ----------------- // Someone implements FAST algorithms for fixed-size ranges namespace fast { // ranges using FAST iterators will have this traversal_category struct traversal_tag {}; // An algorithm implementation strategy template struct unrolled; TYPEOF_REGISTER_TEMPLATE(fast,unrolled,5) // Any algorithm operating on two FAST ranges will use the // unrolled algorithm implementation. template unrolled lookup_implementation(AlgorithmID,fast::traversal_tag,fast::traversal_tag) { return unrolled(); } // Implement the unrolled copy algorithm template <> struct unrolled< algorithm::copy_tag > { // Result type computer template struct result_type { typedef int* type; // would usually be more interesting }; // Implementation template static int* execute(Range1 const&, Range2&) { return 0; } }; // Other unrolled algorithm implementations here... } // ----------------- #include #include #include // Someone implements hierarchical algorithms for segmented iterator ranges namespace segmented { // ranges using segmented iterators will have this traversal_category struct traversal_tag {}; // An algorithm implementation strategy template struct hierarchical; TYPEOF_REGISTER_TEMPLATE(segmented,hierarchical,7) // Unless other overloads match better, any algorithm operating on // any segmented iterator range will use the hierarchical algorithm // implementation. template typename boost::enable_if< boost::mpl::or_< boost::is_convertible , boost::is_convertible > , hierarchical >::type lookup_implementation(AlgorithmID,Traversal1,Traversal2) { return hierarchical(); } // Implement the hierarchical copy algorithm template <> struct hierarchical< algorithm::copy_tag > { // Result type computer template struct result_type { typedef Range2 type; }; // Implementation template static Range2 execute(Range1 const&, Range2& x) { return x; } }; // Other hierarchical algorithm implementations here... } // ----------------- // I implement a fixed-size range namespace my { struct range{/*...*/}; } // and indicate its traversal_category namespace algorithm { template <> struct traversal_category { typedef fast::traversal_tag type; }; } // ----------------- // She implements a segmented range // and indicates its traversal_category namespace her { struct range { typedef segmented::traversal_tag traversal_category; }; } // ----------------- // Test code my::range mine; her::range hers; int* x1 = algorithm::copy(mine, mine); her::range x2 = algorithm::copy(mine, hers); my::range x3 = algorithm::copy(hers, mine); her::range x4 = algorithm::copy(hers, hers); int main() {}