File indexing completed on 2025-01-18 09:50:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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