template struct super_domain; struct dummy_domain; struct default_domain; struct not_a_domain { typedef not_a_domain proto_super_domain; }; template struct domain { typedef Domain proto_super_domain; }; template<> struct domain { typedef dummy_domain proto_super_domain; }; struct dummy_domain : domain<> {}; struct default_domain : domain<> {}; struct not_a_domain_base {}; struct default_domain_base {}; struct dummy_domain_base : default_domain_base {}; template<> struct super_domain : not_a_domain_base { super_domain test(...); not_a_domain get_super(); }; template<> struct super_domain : default_domain_base { template T test(T); default_domain get_super(); }; template struct super_domain : dummy_domain_base { super_domain test(...); super_domain test(default_domain_base); super_domain test(dummy_domain_base); super_domain test(super_domain); Domain get_super(); }; template struct super_domain : super_domain { using super_domain::test; super_domain test(super_domain); super_domain test(default_domain_base); Domain get_super(); }; template struct deduce_domain3 { static super_domain & d0; static super_domain & d1; static super_domain & d2; typedef decltype(d0.test(d1).test(d1).test(d2).test(d2).get_super()) type; }; // Begin test code #include #include struct D0 : domain<> { }; struct D1 : domain { }; struct D2 : domain { }; struct D3 : domain<> { }; struct DD0 : domain { }; struct DD1 : domain { }; struct DD2 : domain { }; struct DD3 : domain { }; struct DD4 : domain { }; int main() { using boost::is_same; //* BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, default_domain>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, DD0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D1>)); // Very tricky to get right BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D0>)); BOOST_MPL_ASSERT((is_same::type, D1>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); // These should be ambiguous. BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); //*/ }