Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file deduce_domain.hpp Chris@16: /// Contains definition of deduce_domain\<\> class templates Chris@16: /// for finding the domain that is common among the specified Chris@16: /// domains Chris@16: // Chris@16: // Copyright 2010 Daniel Wallin, Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // Many thanks to Daniel Wallin who first implemented this code. Thanks Chris@16: // also to Jeremiah Willcock, John Bytheway and Krishna Achuthan who Chris@16: // offered alternate solutions to this tricky programming problem. Chris@16: Chris@16: #ifndef BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010 Chris@16: #define BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifndef BOOST_PROTO_ASSERT_VALID_DOMAIN Chris@16: # define BOOST_PROTO_ASSERT_VALID_DOMAIN(DOM) BOOST_MPL_ASSERT_NOT((boost::is_same)) Chris@16: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace proto Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct domain_ Chris@16: : domain_ Chris@16: { Chris@16: typedef Domain type; Chris@16: typedef domain_ base; Chris@16: #ifdef BOOST_NO_CXX11_DECLTYPE Chris@16: using base::deduce98; Chris@16: static int const index = base::index + 1; Chris@16: static typename sized_type::type deduce98(domain_*); Chris@16: #else Chris@16: using base::deduce0x; Chris@16: static Domain deduce0x(domain_*); Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct domain_ Chris@16: { Chris@16: typedef not_a_domain type; Chris@16: #ifdef BOOST_NO_CXX11_DECLTYPE Chris@16: static int const index = 1; Chris@16: static sized_type<1>::type deduce98(void*); Chris@16: #else Chris@16: static not_a_domain deduce0x(void*); Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct domain_ Chris@16: : domain_ Chris@16: {}; Chris@16: Chris@16: template<> Chris@16: struct domain_ Chris@16: : domain_ Chris@16: {}; Chris@16: Chris@16: sized_type<1>::type default_test(void*, void*); Chris@16: sized_type<2>::type default_test(domain_*, void*); Chris@16: sized_type<2>::type default_test(domain_*, void*); Chris@16: sized_type<3>::type default_test(void*, domain_*); Chris@16: sized_type<3>::type default_test(void*, domain_*); Chris@16: sized_type<4>::type default_test(domain_*, domain_*); Chris@16: sized_type<4>::type default_test(domain_*, domain_*); Chris@16: sized_type<4>::type default_test(domain_*, domain_*); Chris@16: sized_type<4>::type default_test(domain_*, domain_*); Chris@16: Chris@16: #ifdef BOOST_NO_CXX11_DECLTYPE Chris@16: template Chris@16: struct nth_domain Chris@16: : nth_domain Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct nth_domain<0, Domain> Chris@16: : Domain Chris@16: {}; Chris@16: #endif Chris@16: Chris@16: template Chris@16: struct common_domain1 Chris@16: { Chris@16: typedef D0 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct deduce_domain1 Chris@16: : domain_of Chris@16: {}; Chris@16: Chris@16: template< Chris@16: typename D0 Chris@16: , typename D1 Chris@16: , int DefaultCase = sizeof(proto::detail::default_test((domain_*)0, (domain_*)0)) Chris@16: > Chris@16: struct common_domain2 Chris@16: { Chris@16: #ifdef BOOST_NO_CXX11_DECLTYPE Chris@16: static int const index = domain_::index - sizeof(domain_::deduce98((domain_*)0)); Chris@16: typedef typename nth_domain >::type type; Chris@16: #else Chris@16: typedef decltype(domain_::deduce0x((domain_*)0)) type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D1 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D0 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D0 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D0 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D1 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef D1 type; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef default_domain type; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef default_domain type; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef default_domain type; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct common_domain2 Chris@16: { Chris@16: typedef basic_default_domain type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct deduce_domain2 Chris@16: : common_domain2< Chris@16: typename domain_of::type Chris@16: , typename domain_of::type Chris@16: > Chris@16: {}; Chris@16: Chris@16: #include Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: #endif // BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010