#include #include struct not_a_domain { typedef not_a_domain proto_super_domain; }; template struct domain { typedef Domain proto_super_domain; }; struct default_domain : domain<> {}; template struct deduce_domain3 { /* your implementation goes here */ }; struct D0 : domain<> { }; struct D1 : domain // a sub-domain of D0 { }; struct D2 : domain // a sub-domain of D0 { }; struct D3 : domain<> { }; struct DD0 : domain // a sub-domain of default_domain { }; struct DD1 : domain // a sub-domain of default_domain { }; struct DD2 : domain // a sub-domain of default_domain { }; struct DD3 : domain // a sub-domain of DD2 { }; 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>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); BOOST_MPL_ASSERT((is_same::type, DD2>)); // 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>)); }