File indexing completed on 2025-01-18 09:50:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
0012 #define BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
0013
0014 #include <boost/preprocessor/cat.hpp>
0015 #include <boost/preprocessor/arithmetic/inc.hpp>
0016 #include <boost/preprocessor/arithmetic/dec.hpp>
0017 #include <boost/preprocessor/arithmetic/sub.hpp>
0018 #include <boost/preprocessor/punctuation/comma_if.hpp>
0019 #include <boost/preprocessor/iteration/iterate.hpp>
0020 #include <boost/preprocessor/facilities/intercept.hpp>
0021 #include <boost/preprocessor/repetition/enum.hpp>
0022 #include <boost/preprocessor/repetition/enum_params.hpp>
0023 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0024 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
0025 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0026 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0027 #include <boost/preprocessor/repetition/repeat.hpp>
0028 #include <boost/ref.hpp>
0029 #include <boost/mpl/if.hpp>
0030 #include <boost/mpl/assert.hpp>
0031 #include <boost/mpl/eval_if.hpp>
0032 #include <boost/utility/enable_if.hpp>
0033 #include <boost/type_traits/add_const.hpp>
0034 #include <boost/type_traits/add_reference.hpp>
0035 #include <boost/type_traits/remove_cv.hpp>
0036 #include <boost/proto/proto_fwd.hpp>
0037 #include <boost/proto/traits.hpp>
0038 #include <boost/proto/domain.hpp>
0039 #include <boost/proto/generate.hpp>
0040 #include <boost/fusion/include/at_c.hpp>
0041 #include <boost/fusion/include/begin.hpp>
0042 #include <boost/fusion/include/next.hpp>
0043 #include <boost/fusion/include/value_of.hpp>
0044 #include <boost/fusion/include/size.hpp>
0045 #include <boost/proto/detail/poly_function.hpp>
0046 #include <boost/proto/detail/deprecated.hpp>
0047
0048 #if defined(_MSC_VER)
0049 # pragma warning(push)
0050 # pragma warning(disable : 4180)
0051 # pragma warning(disable : 4714)
0052 #endif
0053
0054 namespace boost { namespace proto
0055 {
0056
0057
0058 #define BOOST_PROTO_AS_CHILD_TYPE(Z, N, DATA) \
0059 typename boost::proto::detail::protoify< \
0060 BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
0061 , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
0062 >::result_type \
0063
0064
0065
0066
0067 #define BOOST_PROTO_AS_CHILD(Z, N, DATA) \
0068 boost::proto::detail::protoify< \
0069 BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
0070 , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
0071 >()(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \
0072
0073
0074 namespace detail
0075 {
0076 template<typename T, typename Domain>
0077 struct protoify
0078 : Domain::template as_expr<T>
0079 {};
0080
0081 template<typename T, typename Domain>
0082 struct protoify<T &, Domain>
0083 : Domain::template as_child<T>
0084 {};
0085
0086 template<typename T, typename Domain>
0087 struct protoify<boost::reference_wrapper<T>, Domain>
0088 : Domain::template as_child<T>
0089 {};
0090
0091 template<typename T, typename Domain>
0092 struct protoify<boost::reference_wrapper<T> const, Domain>
0093 : Domain::template as_child<T>
0094 {};
0095
0096
0097 #include <boost/proto/detail/unpack_expr_.hpp>
0098
0099
0100 #include <boost/proto/detail/make_expr_.hpp>
0101 }
0102
0103 namespace result_of
0104 {
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 template<
0117 typename Tag
0118 , BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
0119 , typename Void1
0120 , typename Void2
0121 >
0122 struct make_expr
0123 {
0124
0125
0126
0127
0128
0129
0130
0131 typedef
0132 typename detail::make_expr_<
0133 Tag
0134 , deduce_domain
0135 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
0136 >::result_type
0137 type;
0138 };
0139
0140
0141
0142
0143
0144
0145 template<
0146 typename Tag
0147 , typename Domain
0148 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
0149 >
0150 struct make_expr<
0151 Tag
0152 , Domain
0153 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
0154 , typename Domain::proto_is_domain_
0155 >
0156 {
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 typedef
0180 typename detail::make_expr_<
0181 Tag
0182 , Domain
0183 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
0184 >::result_type
0185 type;
0186 };
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 template<
0202 typename Tag
0203 , typename Sequence
0204 , typename Void1
0205 , typename Void2
0206 >
0207 struct unpack_expr
0208 {
0209
0210
0211
0212
0213
0214
0215 typedef
0216 typename detail::unpack_expr_<
0217 Tag
0218 , deduce_domain
0219 , Sequence
0220 , fusion::result_of::size<Sequence>::type::value
0221 >::type
0222 type;
0223 };
0224
0225
0226
0227
0228
0229
0230 template<typename Tag, typename Domain, typename Sequence>
0231 struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
0232 {
0233
0234
0235
0236
0237
0238
0239 typedef
0240 typename detail::unpack_expr_<
0241 Tag
0242 , Domain
0243 , Sequence
0244 , fusion::result_of::size<Sequence>::type::value
0245 >::type
0246 type;
0247 };
0248 }
0249
0250 namespace functional
0251 {
0252
0253
0254
0255
0256
0257
0258
0259
0260 template<typename Tag, typename Domain >
0261 struct make_expr
0262 {
0263 BOOST_PROTO_CALLABLE()
0264 BOOST_PROTO_POLY_FUNCTION()
0265
0266 template<typename Sig>
0267 struct result;
0268
0269 template<typename This, typename A0>
0270 struct result<This(A0)>
0271 {
0272 typedef
0273 typename result_of::make_expr<
0274 Tag
0275 , Domain
0276 , A0
0277 >::type
0278 type;
0279 };
0280
0281
0282
0283
0284
0285 template<typename A0>
0286 BOOST_FORCEINLINE
0287 typename result_of::make_expr<
0288 Tag
0289 , Domain
0290 , A0 const
0291 >::type const
0292 operator ()(A0 const &a0) const
0293 {
0294 return proto::detail::make_expr_<
0295 Tag
0296 , Domain
0297 , A0 const
0298 >()(a0);
0299 }
0300
0301
0302 #include <boost/proto/detail/make_expr_funop.hpp>
0303
0304
0305
0306 template<
0307 BOOST_PP_ENUM_BINARY_PARAMS(
0308 BOOST_PROTO_MAX_ARITY
0309 , typename A
0310 , = void BOOST_PP_INTERCEPT
0311 )
0312 >
0313 struct impl
0314 : detail::make_expr_<
0315 Tag
0316 , Domain
0317 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
0318 >
0319 {};
0320 };
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330 template<typename Tag, typename Domain >
0331 struct unpack_expr
0332 {
0333 BOOST_PROTO_CALLABLE()
0334
0335 template<typename Sig>
0336 struct result;
0337
0338 template<typename This, typename Sequence>
0339 struct result<This(Sequence)>
0340 {
0341 typedef
0342 typename result_of::unpack_expr<
0343 Tag
0344 , Domain
0345 , typename remove_reference<Sequence>::type
0346 >::type
0347 type;
0348 };
0349
0350
0351
0352
0353
0354
0355 template<typename Sequence>
0356 BOOST_FORCEINLINE
0357 typename result_of::unpack_expr<Tag, Domain, Sequence const>::type const
0358 operator ()(Sequence const &sequence) const
0359 {
0360 return proto::detail::unpack_expr_<
0361 Tag
0362 , Domain
0363 , Sequence const
0364 , fusion::result_of::size<Sequence>::type::value
0365 >::call(sequence);
0366 }
0367 };
0368
0369 }
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 template<typename Tag, typename A0>
0393 BOOST_FORCEINLINE
0394 typename lazy_disable_if<
0395 is_domain<A0>
0396 , result_of::make_expr<
0397 Tag
0398 , A0 const
0399 >
0400 >::type const
0401 make_expr(A0 const &a0)
0402 {
0403 return proto::detail::make_expr_<
0404 Tag
0405 , deduce_domain
0406 , A0 const
0407 >()(a0);
0408 }
0409
0410
0411
0412 template<typename Tag, typename Domain, typename C0>
0413 BOOST_FORCEINLINE
0414 typename result_of::make_expr<
0415 Tag
0416 , Domain
0417 , C0 const
0418 >::type const
0419 make_expr(C0 const &c0)
0420 {
0421 return proto::detail::make_expr_<
0422 Tag
0423 , Domain
0424 , C0 const
0425 >()(c0);
0426 }
0427
0428
0429 #include <boost/proto/detail/make_expr.hpp>
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458 template<typename Tag, typename Sequence>
0459 BOOST_FORCEINLINE
0460 typename lazy_disable_if<
0461 is_domain<Sequence>
0462 , result_of::unpack_expr<Tag, Sequence const>
0463 >::type const
0464 unpack_expr(Sequence const &sequence)
0465 {
0466 return proto::detail::unpack_expr_<
0467 Tag
0468 , deduce_domain
0469 , Sequence const
0470 , fusion::result_of::size<Sequence>::type::value
0471 >::call(sequence);
0472 }
0473
0474
0475
0476 template<typename Tag, typename Domain, typename Sequence2>
0477 BOOST_FORCEINLINE
0478 typename result_of::unpack_expr<Tag, Domain, Sequence2 const>::type const
0479 unpack_expr(Sequence2 const &sequence2)
0480 {
0481 return proto::detail::unpack_expr_<
0482 Tag
0483 , Domain
0484 , Sequence2 const
0485 , fusion::result_of::size<Sequence2>::type::value
0486 >::call(sequence2);
0487 }
0488
0489
0490
0491 template<typename Tag, typename Domain>
0492 struct is_callable<functional::make_expr<Tag, Domain> >
0493 : mpl::true_
0494 {};
0495
0496
0497
0498 template<typename Tag, typename Domain>
0499 struct is_callable<functional::unpack_expr<Tag, Domain> >
0500 : mpl::true_
0501 {};
0502
0503 }}
0504
0505 #if defined(_MSC_VER)
0506 # pragma warning(pop)
0507 #endif
0508
0509 #endif