Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:26

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file deduce_domain.hpp
0003 /// Contains definition of deduce_domain\<\> class templates 
0004 /// for finding the domain that is common among the specified
0005 /// domains
0006 //
0007 //  Copyright 2010 Daniel Wallin, Eric Niebler. Distributed under the Boost
0008 //  Software License, Version 1.0. (See accompanying file
0009 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Many thanks to Daniel Wallin who first implemented this code. Thanks
0012 // also to Jeremiah Willcock, John Bytheway and Krishna Achuthan who
0013 // offered alternate solutions to this tricky programming problem.
0014 
0015 #ifndef BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010
0016 #define BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/preprocessor/cat.hpp>
0020 #include <boost/preprocessor/facilities/intercept.hpp>
0021 #include <boost/preprocessor/iteration/local.hpp>
0022 #include <boost/preprocessor/iteration/iterate.hpp>
0023 #include <boost/preprocessor/repetition/enum_params.hpp>
0024 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0025 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0026 #include <boost/preprocessor/arithmetic/inc.hpp>
0027 #include <boost/mpl/assert.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029 #include <boost/proto/proto_fwd.hpp>
0030 
0031 #ifndef BOOST_PROTO_ASSERT_VALID_DOMAIN
0032 # define BOOST_PROTO_ASSERT_VALID_DOMAIN(DOM) BOOST_MPL_ASSERT_NOT((boost::is_same<DOM, boost::proto::detail::not_a_domain>))
0033 #endif
0034 
0035 namespace boost
0036 {
0037     namespace proto
0038     {
0039         namespace detail
0040         {
0041             template<typename Domain>
0042             struct domain_
0043               : domain_<typename Domain::proto_super_domain>
0044             {
0045                 typedef Domain type;
0046                 typedef domain_<typename Domain::proto_super_domain> base;
0047             #ifdef BOOST_NO_CXX11_DECLTYPE
0048                 using base::deduce98;
0049                 static int const index = base::index + 1;
0050                 static typename sized_type<index>::type deduce98(domain_<Domain>*);
0051             #else
0052                 using base::deduce0x;
0053                 static Domain deduce0x(domain_<Domain>*);
0054             #endif
0055             };
0056 
0057             template<>
0058             struct domain_<not_a_domain>
0059             {
0060                 typedef not_a_domain type;
0061             #ifdef BOOST_NO_CXX11_DECLTYPE
0062                 static int const index = 1;
0063                 static sized_type<1>::type deduce98(void*);
0064             #else
0065                 static not_a_domain deduce0x(void*);
0066             #endif
0067             };
0068 
0069             template<>
0070             struct domain_<default_domain>
0071               : domain_<not_a_domain>
0072             {};
0073 
0074             template<>
0075             struct domain_<basic_default_domain>
0076               : domain_<not_a_domain>
0077             {};
0078 
0079             sized_type<1>::type default_test(void*, void*);
0080             sized_type<2>::type default_test(domain_<default_domain>*, void*);
0081             sized_type<2>::type default_test(domain_<basic_default_domain>*, void*);
0082             sized_type<3>::type default_test(void*, domain_<default_domain>*);
0083             sized_type<3>::type default_test(void*, domain_<basic_default_domain>*);
0084             sized_type<4>::type default_test(domain_<default_domain>*, domain_<default_domain>*);
0085             sized_type<4>::type default_test(domain_<basic_default_domain>*, domain_<default_domain>*);
0086             sized_type<4>::type default_test(domain_<default_domain>*, domain_<basic_default_domain>*);
0087             sized_type<4>::type default_test(domain_<basic_default_domain>*, domain_<basic_default_domain>*);
0088 
0089         #ifdef BOOST_NO_CXX11_DECLTYPE
0090             template<int N, typename Domain>
0091             struct nth_domain
0092               : nth_domain<N - 1, typename Domain::base>
0093             {};
0094 
0095             template<typename Domain>
0096             struct nth_domain<0, Domain>
0097               : Domain
0098             {};
0099         #endif
0100 
0101             template<typename D0>
0102             struct common_domain1
0103             {
0104                 typedef D0 type;
0105             };
0106 
0107             template<typename E0>
0108             struct deduce_domain1
0109               : domain_of<E0>
0110             {};
0111 
0112             template<
0113                 typename D0
0114               , typename D1
0115               , int DefaultCase = sizeof(proto::detail::default_test((domain_<D0>*)0, (domain_<D1>*)0))
0116             >
0117             struct common_domain2
0118             {
0119             #ifdef BOOST_NO_CXX11_DECLTYPE
0120                 static int const index = domain_<D0>::index - sizeof(domain_<D0>::deduce98((domain_<D1>*)0));
0121                 typedef typename nth_domain<index, domain_<D0> >::type type;
0122             #else
0123                 typedef decltype(domain_<D0>::deduce0x((domain_<D1>*)0)) type;
0124             #endif
0125             };
0126 
0127             template<typename D0, typename D1>
0128             struct common_domain2<D0, D1, 2>
0129             {
0130                 typedef D1 type;
0131             };
0132 
0133             template<typename D0, typename D1>
0134             struct common_domain2<D0, D1, 3>
0135             {
0136                 typedef D0 type;
0137             };
0138 
0139             template<typename D0>
0140             struct common_domain2<D0, default_domain, 4>
0141             {
0142                 typedef D0 type;
0143             };
0144 
0145             template<typename D0>
0146             struct common_domain2<D0, basic_default_domain, 4>
0147             {
0148                 typedef D0 type;
0149             };
0150 
0151             template<typename D1>
0152             struct common_domain2<default_domain, D1, 4>
0153             {
0154                 typedef D1 type;
0155             };
0156 
0157             template<typename D1>
0158             struct common_domain2<basic_default_domain, D1, 4>
0159             {
0160                 typedef D1 type;
0161             };
0162 
0163             template<>
0164             struct common_domain2<default_domain, default_domain, 4>
0165             {
0166                 typedef default_domain type;
0167             };
0168 
0169             template<>
0170             struct common_domain2<basic_default_domain, default_domain, 4>
0171             {
0172                 typedef default_domain type;
0173             };
0174 
0175             template<>
0176             struct common_domain2<default_domain, basic_default_domain, 4>
0177             {
0178                 typedef default_domain type;
0179             };
0180 
0181             template<>
0182             struct common_domain2<basic_default_domain, basic_default_domain, 4>
0183             {
0184                 typedef basic_default_domain type;
0185             };
0186 
0187             template<typename E0, typename E1>
0188             struct deduce_domain2
0189               : common_domain2<
0190                     typename domain_of<E0>::type
0191                   , typename domain_of<E1>::type
0192                 >
0193             {};
0194 
0195             #include <boost/proto/detail/deduce_domain_n.hpp>
0196         }
0197     }
0198 }
0199 
0200 #endif // BOOST_PROTO_DEDUCE_DOMAIN_HPP_EAN_05_22_2010