File indexing completed on 2025-01-19 09:47:48
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM)
0007 #define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/spirit/home/support/unused.hpp>
0014
0015 #include <boost/version.hpp>
0016 #include <boost/proto/make_expr.hpp>
0017 #include <boost/proto/traits.hpp>
0018 #include <boost/utility/result_of.hpp>
0019 #include <boost/type_traits/add_const.hpp>
0020 #include <boost/type_traits/add_reference.hpp>
0021 #include <boost/type_traits/remove_const.hpp>
0022 #include <boost/type_traits/remove_reference.hpp>
0023 #include <boost/fusion/include/fold.hpp>
0024 #include <boost/mpl/and.hpp>
0025 #include <boost/mpl/not.hpp>
0026
0027
0028 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
0029 #include <boost/type_traits/is_same.hpp>
0030 #endif
0031
0032 namespace boost { namespace spirit { namespace traits
0033 {
0034
0035
0036 template <typename Domain, typename T, typename Enable = void>
0037 struct meta_create;
0038
0039
0040
0041
0042 template <typename Domain, typename T, typename Enable = void>
0043 struct meta_create_exists : mpl::false_ {};
0044 }}}
0045
0046 namespace boost { namespace spirit
0047 {
0048
0049 namespace detail
0050 {
0051 template <typename T>
0052 struct add_const_ref
0053 : add_reference<typename add_const<T>::type> {};
0054
0055 template <typename T>
0056 struct remove_const_ref
0057 : remove_const<typename remove_reference<T>::type> {};
0058
0059
0060
0061
0062 #if BOOST_VERSION < 104200
0063
0064 template <typename OpTag, typename Domain>
0065 struct nary_proto_expr_function
0066 {
0067 template <typename T>
0068 struct result;
0069
0070
0071
0072 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
0073 template <typename F, typename T1, typename T2>
0074 struct result<F(T1, T2)>
0075 {
0076 BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
0077 #else
0078 template <typename T1, typename T2>
0079 struct result<nary_proto_expr_function(T1, T2)>
0080 {
0081 #endif
0082 typedef typename remove_const_ref<T2>::type left_type;
0083 typedef typename
0084 spirit::traits::meta_create<Domain, T1>::type
0085 right_type;
0086
0087 typedef typename mpl::eval_if<
0088 traits::not_is_unused<left_type>
0089 , proto::result_of::make_expr<OpTag, left_type, right_type>
0090 , mpl::identity<right_type>
0091 >::type type;
0092 };
0093
0094 template <typename T>
0095 typename result<nary_proto_expr_function(T, unused_type const&)>::type
0096 operator()(T, unused_type const&) const
0097 {
0098 typedef spirit::traits::meta_create<Domain, T> right_type;
0099 return right_type::call();
0100 }
0101
0102 template <typename T1, typename T2>
0103 typename result<nary_proto_expr_function(T1, T2)>::type
0104 operator()(T1, T2 const& t2) const
0105 {
0106
0107 typedef spirit::traits::meta_create<Domain, T1> right_type;
0108 return proto::make_expr<OpTag>(t2, right_type::call());
0109 }
0110 };
0111 #else
0112
0113 template <typename OpTag, typename Domain>
0114 struct nary_proto_expr_function
0115 {
0116 template <typename T>
0117 struct result;
0118
0119
0120
0121 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
0122 template <typename F, typename T1, typename T2>
0123 struct result<F(T1, T2)>
0124 {
0125 BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
0126 #else
0127 template <typename T1, typename T2>
0128 struct result<nary_proto_expr_function(T1, T2)>
0129 {
0130 #endif
0131 typedef typename remove_const_ref<T1>::type left_type;
0132 typedef typename
0133 spirit::traits::meta_create<Domain, T2>::type
0134 right_type;
0135
0136 typedef typename mpl::eval_if<
0137 traits::not_is_unused<left_type>
0138 , proto::result_of::make_expr<OpTag, left_type, right_type>
0139 , mpl::identity<right_type>
0140 >::type type;
0141 };
0142
0143 template <typename T>
0144 typename result<nary_proto_expr_function(unused_type const&, T)>::type
0145 operator()(unused_type const&, T) const
0146 {
0147 typedef spirit::traits::meta_create<Domain, T> right_type;
0148 return right_type::call();
0149 }
0150
0151 template <typename T1, typename T2>
0152 typename result<nary_proto_expr_function(T1, T2)>::type
0153 operator()(T1 const& t1, T2) const
0154 {
0155
0156 typedef spirit::traits::meta_create<Domain, T2> right_type;
0157 return proto::make_expr<OpTag>(t1, right_type::call());
0158 }
0159 };
0160 #endif
0161 }
0162
0163
0164 template <typename T, typename OpTag, typename Domain>
0165 struct make_unary_proto_expr
0166 {
0167 typedef spirit::traits::meta_create<Domain, T> subject_type;
0168
0169 typedef typename proto::result_of::make_expr<
0170 OpTag, typename subject_type::type
0171 >::type type;
0172
0173 static type call()
0174 {
0175 return proto::make_expr<OpTag>(subject_type::call());
0176 }
0177 };
0178
0179
0180 template <typename Sequence, typename OpTag, typename Domain>
0181 struct make_nary_proto_expr
0182 {
0183 typedef detail::nary_proto_expr_function<OpTag, Domain>
0184 make_proto_expr;
0185
0186 typedef typename fusion::result_of::fold<
0187 Sequence, unused_type, make_proto_expr
0188 >::type type;
0189
0190 static type call()
0191 {
0192 return fusion::fold(Sequence(), unused, make_proto_expr());
0193 }
0194 };
0195
0196
0197 namespace detail
0198 {
0199
0200
0201
0202
0203 template <typename T>
0204 struct is_fusion_sequence_but_not_proto_expr
0205 : mpl::and_<
0206 fusion::traits::is_sequence<T>
0207 , mpl::not_<proto::is_expr<T> > >
0208 {};
0209 }
0210 }}
0211
0212 #endif