annotate DEPENDENCIES/generic/include/boost/proto/extends.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file extends.hpp
Chris@16 3 /// Macros and a base class for defining end-user expression types
Chris@16 4 //
Chris@16 5 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 6 // Software License, Version 1.0. (See accompanying file
Chris@16 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #ifndef BOOST_PROTO_EXTENDS_HPP_EAN_11_1_2006
Chris@16 10 #define BOOST_PROTO_EXTENDS_HPP_EAN_11_1_2006
Chris@16 11
Chris@16 12 #include <cstddef> // for offsetof
Chris@16 13 #include <boost/config.hpp>
Chris@16 14 #include <boost/detail/workaround.hpp>
Chris@16 15 #include <boost/preprocessor/facilities/empty.hpp>
Chris@16 16 #include <boost/preprocessor/tuple/elem.hpp>
Chris@16 17 #include <boost/preprocessor/control/if.hpp>
Chris@16 18 #include <boost/preprocessor/arithmetic/inc.hpp>
Chris@16 19 #include <boost/preprocessor/arithmetic/dec.hpp>
Chris@16 20 #include <boost/preprocessor/iteration/local.hpp>
Chris@16 21 #include <boost/preprocessor/repetition/enum_params.hpp>
Chris@16 22 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
Chris@16 23 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
Chris@16 24 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
Chris@16 25 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
Chris@16 26 #include <boost/preprocessor/seq/for_each.hpp>
Chris@16 27 #include <boost/utility/addressof.hpp>
Chris@16 28 #include <boost/utility/result_of.hpp>
Chris@16 29 #include <boost/proto/proto_fwd.hpp>
Chris@16 30 #include <boost/proto/traits.hpp>
Chris@16 31 #include <boost/proto/expr.hpp>
Chris@16 32 #include <boost/proto/args.hpp>
Chris@16 33 #include <boost/proto/traits.hpp>
Chris@16 34 #include <boost/proto/generate.hpp>
Chris@16 35 #include <boost/proto/detail/remove_typename.hpp>
Chris@16 36
Chris@101 37 #if defined(_MSC_VER)
Chris@16 38 # pragma warning(push)
Chris@16 39 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
Chris@16 40 #endif
Chris@16 41
Chris@16 42 namespace boost { namespace proto
Chris@16 43 {
Chris@16 44 #ifdef __GNUC__
Chris@16 45 /// INTERNAL ONLY
Chris@16 46 ///
Chris@16 47 # define BOOST_PROTO_ADDROF(x) ((char const volatile*)boost::addressof(x))
Chris@16 48 /// INTERNAL ONLY
Chris@16 49 ///
Chris@16 50 # define BOOST_PROTO_OFFSETOF(s,m) (BOOST_PROTO_ADDROF((((s *)this)->m)) - BOOST_PROTO_ADDROF(*((s *)this)))
Chris@16 51 #else
Chris@16 52 /// INTERNAL ONLY
Chris@16 53 ///
Chris@16 54 # define BOOST_PROTO_OFFSETOF offsetof
Chris@16 55 #endif
Chris@16 56
Chris@16 57 /// INTERNAL ONLY
Chris@16 58 ///
Chris@16 59 #define BOOST_PROTO_CONST() const
Chris@16 60
Chris@16 61 /// INTERNAL ONLY
Chris@16 62 ///
Chris@16 63 #define BOOST_PROTO_TYPENAME() typename
Chris@16 64
Chris@16 65 /// INTERNAL ONLY
Chris@16 66 ///
Chris@16 67 #define BOOST_PROTO_TEMPLATE_YES_(Z, N) template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)>
Chris@16 68
Chris@16 69 /// INTERNAL ONLY
Chris@16 70 ///
Chris@16 71 #define BOOST_PROTO_TEMPLATE_NO_(Z, N)
Chris@16 72
Chris@16 73 /// INTERNAL ONLY
Chris@16 74 ///
Chris@16 75 #define BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, Const) \
Chris@16 76 BOOST_PP_IF(N, BOOST_PROTO_TEMPLATE_YES_, BOOST_PROTO_TEMPLATE_NO_)(Z, N) \
Chris@16 77 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 78 typename BOOST_PROTO_RESULT_OF< \
Chris@16 79 proto_generator( \
Chris@16 80 typename boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
Chris@16 81 proto_derived_expr Const() \
Chris@16 82 , proto_domain \
Chris@16 83 BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
Chris@16 84 >::type \
Chris@16 85 ) \
Chris@16 86 >::type const \
Chris@16 87 operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) Const() \
Chris@16 88 { \
Chris@16 89 typedef boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
Chris@16 90 proto_derived_expr Const() \
Chris@16 91 , proto_domain \
Chris@16 92 BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
Chris@16 93 > funop; \
Chris@16 94 return proto_generator()( \
Chris@16 95 funop::call( \
Chris@16 96 *static_cast<proto_derived_expr Const() *>(this) \
Chris@16 97 BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, a) \
Chris@16 98 ) \
Chris@16 99 ); \
Chris@16 100 } \
Chris@16 101 /**/
Chris@16 102
Chris@16 103 /// INTERNAL ONLY
Chris@16 104 ///
Chris@16 105 #define BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(Const) \
Chris@16 106 template<typename... A> \
Chris@16 107 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 108 typename BOOST_PROTO_RESULT_OF< \
Chris@16 109 proto_generator( \
Chris@16 110 typename boost::proto::result_of::funop< \
Chris@16 111 proto_derived_expr Const()(A const &...) \
Chris@16 112 , proto_derived_expr \
Chris@16 113 , proto_domain \
Chris@16 114 >::type \
Chris@16 115 ) \
Chris@16 116 >::type const \
Chris@16 117 operator ()(A const &...a) Const() \
Chris@16 118 { \
Chris@16 119 typedef boost::proto::result_of::funop< \
Chris@16 120 proto_derived_expr Const()(A const &...) \
Chris@16 121 , proto_derived_expr \
Chris@16 122 , proto_domain \
Chris@16 123 > funop; \
Chris@16 124 return proto_generator()( \
Chris@16 125 funop::call( \
Chris@16 126 *static_cast<proto_derived_expr Const() *>(this) \
Chris@16 127 , a... \
Chris@16 128 ) \
Chris@16 129 ); \
Chris@16 130 } \
Chris@16 131 /**/
Chris@16 132
Chris@16 133 /// INTERNAL ONLY
Chris@16 134 ///
Chris@16 135 #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
Chris@16 136 BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, BOOST_PROTO_CONST) \
Chris@16 137 /**/
Chris@16 138
Chris@16 139 /// INTERNAL ONLY
Chris@16 140 ///
Chris@16 141 #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
Chris@16 142 BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, BOOST_PP_EMPTY) \
Chris@16 143 /**/
Chris@16 144
Chris@16 145 /// INTERNAL ONLY
Chris@16 146 ///
Chris@16 147 #define BOOST_PROTO_DEFINE_FUN_OP(Z, N, DATA) \
Chris@16 148 BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
Chris@16 149 BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
Chris@16 150 /**/
Chris@16 151
Chris@16 152 /// INTERNAL ONLY
Chris@16 153 ///
Chris@16 154 #define BOOST_PROTO_EXTENDS_CHILD(Z, N, DATA) \
Chris@16 155 typedef \
Chris@16 156 typename proto_base_expr::BOOST_PP_CAT(proto_child, N) \
Chris@16 157 BOOST_PP_CAT(proto_child, N); \
Chris@16 158 /**/
Chris@16 159
Chris@16 160 #define BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain) \
Chris@16 161 Expr proto_expr_; \
Chris@16 162 \
Chris@16 163 typedef Expr proto_base_expr_; /**< INTERNAL ONLY */ \
Chris@16 164 typedef typename proto_base_expr_::proto_base_expr proto_base_expr; \
Chris@16 165 typedef BOOST_PROTO_REMOVE_TYPENAME(Domain) proto_domain; \
Chris@16 166 typedef Derived proto_derived_expr; \
Chris@16 167 typedef Domain::proto_generator proto_generator; \
Chris@16 168 typedef typename proto_base_expr::proto_tag proto_tag; \
Chris@16 169 typedef typename proto_base_expr::proto_args proto_args; \
Chris@16 170 typedef typename proto_base_expr::proto_arity proto_arity; \
Chris@16 171 typedef typename proto_base_expr::proto_grammar proto_grammar; \
Chris@16 172 typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_; \
Chris@16 173 typedef void proto_is_expr_; /**< INTERNAL ONLY */ \
Chris@16 174 static const long proto_arity_c = proto_base_expr::proto_arity_c; \
Chris@16 175 typedef boost::proto::tag::proto_expr<proto_tag, proto_domain> fusion_tag; \
Chris@16 176 BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~) \
Chris@16 177 \
Chris@16 178 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 179 static proto_derived_expr const make(Expr const &e) \
Chris@16 180 { \
Chris@16 181 proto_derived_expr that = {e}; \
Chris@16 182 return that; \
Chris@16 183 } \
Chris@16 184 \
Chris@16 185 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 186 proto_base_expr &proto_base() \
Chris@16 187 { \
Chris@16 188 return this->proto_expr_.proto_base(); \
Chris@16 189 } \
Chris@16 190 \
Chris@16 191 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 192 proto_base_expr const &proto_base() const \
Chris@16 193 { \
Chris@16 194 return this->proto_expr_.proto_base(); \
Chris@16 195 } \
Chris@16 196 \
Chris@16 197 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 198 operator proto_address_of_hack_type_() const \
Chris@16 199 { \
Chris@16 200 return boost::addressof(this->proto_base().child0); \
Chris@16 201 } \
Chris@16 202 /**/
Chris@16 203
Chris@16 204 #define BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
Chris@16 205 BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain) \
Chris@16 206 typedef void proto_is_aggregate_; \
Chris@16 207 /**< INTERNAL ONLY */
Chris@16 208
Chris@16 209 #define BOOST_PROTO_EXTENDS_COPY_ASSIGN_IMPL_(This, Const, Typename) \
Chris@16 210 BOOST_PROTO_DISABLE_MSVC_C4522 \
Chris@16 211 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 212 Typename() BOOST_PROTO_RESULT_OF< \
Chris@16 213 Typename() This::proto_generator( \
Chris@16 214 Typename() boost::proto::base_expr< \
Chris@16 215 Typename() This::proto_domain \
Chris@16 216 , boost::proto::tag::assign \
Chris@16 217 , boost::proto::list2< \
Chris@16 218 This & \
Chris@16 219 , This Const() & \
Chris@16 220 > \
Chris@16 221 >::type \
Chris@16 222 ) \
Chris@16 223 >::type const \
Chris@16 224 operator =(This Const() &a) \
Chris@16 225 { \
Chris@16 226 typedef \
Chris@16 227 Typename() boost::proto::base_expr< \
Chris@16 228 Typename() This::proto_domain \
Chris@16 229 , boost::proto::tag::assign \
Chris@16 230 , boost::proto::list2< \
Chris@16 231 This & \
Chris@16 232 , This Const() & \
Chris@16 233 > \
Chris@16 234 >::type \
Chris@16 235 that_type; \
Chris@16 236 that_type const that = { \
Chris@16 237 *this \
Chris@16 238 , a \
Chris@16 239 }; \
Chris@16 240 return Typename() This::proto_generator()(that); \
Chris@16 241 } \
Chris@16 242 /**/
Chris@16 243
Chris@16 244 // MSVC 8.0 and higher seem to need copy-assignment operator to be overloaded on *both*
Chris@16 245 // const and non-const rhs arguments.
Chris@16 246 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) && (BOOST_MSVC > 1310)
Chris@16 247 #define BOOST_PROTO_EXTENDS_COPY_ASSIGN_(This, Typename) \
Chris@16 248 BOOST_PROTO_EXTENDS_COPY_ASSIGN_IMPL_(This, BOOST_PP_EMPTY, Typename) \
Chris@16 249 BOOST_PROTO_EXTENDS_COPY_ASSIGN_IMPL_(This, BOOST_PROTO_CONST, Typename) \
Chris@16 250 /**/
Chris@16 251 #else
Chris@16 252 #define BOOST_PROTO_EXTENDS_COPY_ASSIGN_(This, Typename) \
Chris@16 253 BOOST_PROTO_EXTENDS_COPY_ASSIGN_IMPL_(This, BOOST_PROTO_CONST, Typename) \
Chris@16 254 /**/
Chris@16 255 #endif
Chris@16 256
Chris@16 257 /// INTERNAL ONLY
Chris@16 258 ///
Chris@16 259 #define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(ThisConst, ThatConst) \
Chris@16 260 template<typename A> \
Chris@16 261 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 262 typename BOOST_PROTO_RESULT_OF< \
Chris@16 263 proto_generator( \
Chris@16 264 typename boost::proto::base_expr< \
Chris@16 265 proto_domain \
Chris@16 266 , boost::proto::tag::assign \
Chris@16 267 , boost::proto::list2< \
Chris@16 268 proto_derived_expr ThisConst() & \
Chris@16 269 , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
Chris@16 270 > \
Chris@16 271 >::type \
Chris@16 272 ) \
Chris@16 273 >::type const \
Chris@16 274 operator =(A ThatConst() &a) ThisConst() \
Chris@16 275 { \
Chris@16 276 typedef \
Chris@16 277 typename boost::proto::base_expr< \
Chris@16 278 proto_domain \
Chris@16 279 , boost::proto::tag::assign \
Chris@16 280 , boost::proto::list2< \
Chris@16 281 proto_derived_expr ThisConst() & \
Chris@16 282 , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
Chris@16 283 > \
Chris@16 284 >::type \
Chris@16 285 that_type; \
Chris@16 286 that_type const that = { \
Chris@16 287 *static_cast<proto_derived_expr ThisConst() *>(this) \
Chris@16 288 , boost::proto::as_child<proto_domain>(a) \
Chris@16 289 }; \
Chris@16 290 return proto_generator()(that); \
Chris@16 291 } \
Chris@16 292 /**/
Chris@16 293
Chris@16 294 #define BOOST_PROTO_EXTENDS_ASSIGN_CONST_() \
Chris@16 295 BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(BOOST_PROTO_CONST, BOOST_PP_EMPTY) \
Chris@16 296 BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(BOOST_PROTO_CONST, BOOST_PROTO_CONST) \
Chris@16 297 /**/
Chris@16 298
Chris@16 299 #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST_() \
Chris@16 300 BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(BOOST_PP_EMPTY, BOOST_PP_EMPTY) \
Chris@16 301 BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(BOOST_PP_EMPTY, BOOST_PROTO_CONST) \
Chris@16 302 /**/
Chris@16 303
Chris@16 304 #define BOOST_PROTO_EXTENDS_ASSIGN_() \
Chris@16 305 BOOST_PROTO_EXTENDS_ASSIGN_CONST_() \
Chris@16 306 BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST_() \
Chris@16 307 /**/
Chris@16 308
Chris@16 309 #define BOOST_PROTO_EXTENDS_ASSIGN_CONST() \
Chris@16 310 BOOST_PROTO_EXTENDS_COPY_ASSIGN_(proto_derived_expr, BOOST_PROTO_TYPENAME) \
Chris@16 311 BOOST_PROTO_EXTENDS_ASSIGN_CONST_() \
Chris@16 312 /**/
Chris@16 313
Chris@16 314 #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST() \
Chris@16 315 BOOST_PROTO_EXTENDS_COPY_ASSIGN_(proto_derived_expr, BOOST_PROTO_TYPENAME) \
Chris@16 316 BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST_() \
Chris@16 317 /**/
Chris@16 318
Chris@16 319 #define BOOST_PROTO_EXTENDS_ASSIGN() \
Chris@16 320 BOOST_PROTO_EXTENDS_COPY_ASSIGN_(proto_derived_expr, BOOST_PROTO_TYPENAME) \
Chris@16 321 BOOST_PROTO_EXTENDS_ASSIGN_() \
Chris@16 322 /**/
Chris@16 323
Chris@16 324 /// INTERNAL ONLY
Chris@16 325 ///
Chris@16 326 #define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(ThisConst, ThatConst) \
Chris@16 327 template<typename A> \
Chris@16 328 BOOST_PROTO_DISABLE_MSVC_C4714 BOOST_FORCEINLINE \
Chris@16 329 typename BOOST_PROTO_RESULT_OF< \
Chris@16 330 proto_generator( \
Chris@16 331 typename boost::proto::base_expr< \
Chris@16 332 proto_domain \
Chris@16 333 , boost::proto::tag::subscript \
Chris@16 334 , boost::proto::list2< \
Chris@16 335 proto_derived_expr ThisConst() & \
Chris@16 336 , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
Chris@16 337 > \
Chris@16 338 >::type \
Chris@16 339 ) \
Chris@16 340 >::type const \
Chris@16 341 operator [](A ThatConst() &a) ThisConst() \
Chris@16 342 { \
Chris@16 343 typedef \
Chris@16 344 typename boost::proto::base_expr< \
Chris@16 345 proto_domain \
Chris@16 346 , boost::proto::tag::subscript \
Chris@16 347 , boost::proto::list2< \
Chris@16 348 proto_derived_expr ThisConst() & \
Chris@16 349 , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
Chris@16 350 > \
Chris@16 351 >::type \
Chris@16 352 that_type; \
Chris@16 353 that_type const that = { \
Chris@16 354 *static_cast<proto_derived_expr ThisConst() *>(this) \
Chris@16 355 , boost::proto::as_child<proto_domain>(a) \
Chris@16 356 }; \
Chris@16 357 return proto_generator()(that); \
Chris@16 358 } \
Chris@16 359 /**/
Chris@16 360
Chris@16 361 #define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
Chris@16 362 BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(BOOST_PROTO_CONST, BOOST_PP_EMPTY) \
Chris@16 363 BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(BOOST_PROTO_CONST, BOOST_PROTO_CONST) \
Chris@16 364 /**/
Chris@16 365
Chris@16 366 #define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
Chris@16 367 BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(BOOST_PP_EMPTY, BOOST_PP_EMPTY) \
Chris@16 368 BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(BOOST_PP_EMPTY, BOOST_PROTO_CONST) \
Chris@16 369 /**/
Chris@16 370
Chris@16 371 #define BOOST_PROTO_EXTENDS_SUBSCRIPT() \
Chris@16 372 BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
Chris@16 373 BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
Chris@16 374 /**/
Chris@16 375
Chris@16 376 /// INTERNAL ONLY
Chris@16 377 ///
Chris@16 378 #define BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 379 template<typename Sig> \
Chris@16 380 struct result \
Chris@16 381 { \
Chris@16 382 typedef \
Chris@16 383 typename BOOST_PROTO_RESULT_OF< \
Chris@16 384 proto_generator( \
Chris@16 385 typename boost::proto::result_of::funop< \
Chris@16 386 Sig \
Chris@16 387 , proto_derived_expr \
Chris@16 388 , proto_domain \
Chris@16 389 >::type \
Chris@16 390 ) \
Chris@16 391 >::type const \
Chris@16 392 type; \
Chris@16 393 }; \
Chris@16 394 /**/
Chris@16 395
Chris@16 396 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
Chris@16 397 #define BOOST_PROTO_EXTENDS_FUNCTION_CONST() \
Chris@16 398 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 399 BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(BOOST_PROTO_CONST) \
Chris@16 400 /**/
Chris@16 401
Chris@16 402 #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST() \
Chris@16 403 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 404 BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(BOOST_PP_EMPTY) \
Chris@16 405 /**/
Chris@16 406
Chris@16 407 #define BOOST_PROTO_EXTENDS_FUNCTION() \
Chris@16 408 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 409 BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(BOOST_PP_EMPTY) \
Chris@16 410 BOOST_PROTO_DEFINE_FUN_OP_VARIADIC_IMPL_(BOOST_PROTO_CONST) \
Chris@16 411 /**/
Chris@16 412 #else
Chris@16 413 #define BOOST_PROTO_EXTENDS_FUNCTION_CONST() \
Chris@16 414 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 415 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 416 0 \
Chris@16 417 , BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
Chris@16 418 , BOOST_PROTO_DEFINE_FUN_OP_CONST \
Chris@16 419 , ~ \
Chris@16 420 ) \
Chris@16 421 /**/
Chris@16 422
Chris@16 423 #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST() \
Chris@16 424 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 425 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 426 0 \
Chris@16 427 , BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
Chris@16 428 , BOOST_PROTO_DEFINE_FUN_OP_NON_CONST \
Chris@16 429 , ~ \
Chris@16 430 ) \
Chris@16 431 /**/
Chris@16 432
Chris@16 433 #define BOOST_PROTO_EXTENDS_FUNCTION() \
Chris@16 434 BOOST_PROTO_EXTENDS_FUNCTION_() \
Chris@16 435 BOOST_PP_REPEAT_FROM_TO( \
Chris@16 436 0 \
Chris@16 437 , BOOST_PROTO_MAX_FUNCTION_CALL_ARITY \
Chris@16 438 , BOOST_PROTO_DEFINE_FUN_OP \
Chris@16 439 , ~ \
Chris@16 440 ) \
Chris@16 441 /**/
Chris@16 442 #endif
Chris@16 443
Chris@16 444 #define BOOST_PROTO_EXTENDS(Expr, Derived, Domain) \
Chris@16 445 BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
Chris@16 446 BOOST_PROTO_EXTENDS_ASSIGN() \
Chris@16 447 BOOST_PROTO_EXTENDS_SUBSCRIPT() \
Chris@16 448 BOOST_PROTO_EXTENDS_FUNCTION() \
Chris@16 449 /**/
Chris@16 450
Chris@16 451 #define BOOST_PROTO_EXTENDS_USING_ASSIGN(Derived) \
Chris@16 452 typedef typename Derived::proto_extends proto_extends; \
Chris@16 453 using proto_extends::operator =; \
Chris@16 454 BOOST_PROTO_EXTENDS_COPY_ASSIGN_(Derived, BOOST_PROTO_TYPENAME) \
Chris@16 455 /**/
Chris@16 456
Chris@16 457 #define BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT(Derived) \
Chris@16 458 typedef Derived::proto_extends proto_extends; \
Chris@16 459 using proto_extends::operator =; \
Chris@16 460 BOOST_PROTO_EXTENDS_COPY_ASSIGN_(Derived, BOOST_PP_EMPTY) \
Chris@16 461 /**/
Chris@16 462
Chris@16 463 namespace exprns_
Chris@16 464 {
Chris@16 465 /// \brief Empty type to be used as a dummy template parameter of
Chris@16 466 /// POD expression wrappers. It allows argument-dependent lookup
Chris@16 467 /// to find Proto's operator overloads.
Chris@16 468 ///
Chris@16 469 /// \c proto::is_proto_expr allows argument-dependent lookup
Chris@16 470 /// to find Proto's operator overloads. For example:
Chris@16 471 ///
Chris@16 472 /// \code
Chris@16 473 /// template<typename T, typename Dummy = proto::is_proto_expr>
Chris@16 474 /// struct my_terminal
Chris@16 475 /// {
Chris@16 476 /// BOOST_PROTO_BASIC_EXTENDS(
Chris@16 477 /// typename proto::terminal<T>::type
Chris@16 478 /// , my_terminal<T>
Chris@16 479 /// , default_domain
Chris@16 480 /// )
Chris@16 481 /// };
Chris@16 482 ///
Chris@16 483 /// // ...
Chris@16 484 /// my_terminal<int> _1, _2;
Chris@16 485 /// _1 + _2; // OK, uses proto::operator+
Chris@16 486 /// \endcode
Chris@16 487 ///
Chris@16 488 /// Without the second \c Dummy template parameter, Proto's operator
Chris@16 489 /// overloads would not be considered by name lookup.
Chris@16 490 struct is_proto_expr
Chris@16 491 {};
Chris@16 492
Chris@16 493 /// \brief extends\<\> class template for adding behaviors to a Proto expression template
Chris@16 494 ///
Chris@16 495 template<
Chris@16 496 typename Expr
Chris@16 497 , typename Derived
Chris@16 498 , typename Domain // = proto::default_domain
Chris@16 499 , long Arity // = Expr::proto_arity_c
Chris@16 500 >
Chris@16 501 struct extends
Chris@16 502 {
Chris@16 503 BOOST_FORCEINLINE
Chris@16 504 extends()
Chris@16 505 : proto_expr_()
Chris@16 506 {}
Chris@16 507
Chris@16 508 BOOST_FORCEINLINE
Chris@16 509 extends(extends const &that)
Chris@16 510 : proto_expr_(that.proto_expr_)
Chris@16 511 {}
Chris@16 512
Chris@16 513 BOOST_FORCEINLINE
Chris@16 514 extends(Expr const &expr_)
Chris@16 515 : proto_expr_(expr_)
Chris@16 516 {}
Chris@16 517
Chris@16 518 typedef extends proto_extends;
Chris@16 519 BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, typename Domain)
Chris@16 520 BOOST_PROTO_EXTENDS_ASSIGN_CONST_()
Chris@16 521 BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST()
Chris@16 522
Chris@16 523 // Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
Chris@16 524 // nested preprocessor loops, use file iteration here to generate
Chris@16 525 // the operator() overloads, which is more efficient.
Chris@16 526 #include <boost/proto/detail/extends_funop_const.hpp>
Chris@16 527 };
Chris@16 528
Chris@16 529 /// \brief extends\<\> class template for adding behaviors to a Proto expression template
Chris@16 530 ///
Chris@16 531 template<typename Expr, typename Derived, typename Domain>
Chris@16 532 struct extends<Expr, Derived, Domain, 0>
Chris@16 533 {
Chris@16 534 BOOST_FORCEINLINE
Chris@16 535 extends()
Chris@16 536 : proto_expr_()
Chris@16 537 {}
Chris@16 538
Chris@16 539 BOOST_FORCEINLINE
Chris@16 540 extends(extends const &that)
Chris@16 541 : proto_expr_(that.proto_expr_)
Chris@16 542 {}
Chris@16 543
Chris@16 544 BOOST_FORCEINLINE
Chris@16 545 extends(Expr const &expr_)
Chris@16 546 : proto_expr_(expr_)
Chris@16 547 {}
Chris@16 548
Chris@16 549 typedef extends proto_extends;
Chris@16 550 BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, typename Domain)
Chris@16 551 BOOST_PROTO_EXTENDS_ASSIGN_()
Chris@16 552 BOOST_PROTO_EXTENDS_SUBSCRIPT()
Chris@16 553
Chris@16 554 // Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
Chris@16 555 // nested preprocessor loops, use file iteration here to generate
Chris@16 556 // the operator() overloads, which is more efficient.
Chris@16 557 #include <boost/proto/detail/extends_funop.hpp>
Chris@16 558 };
Chris@16 559
Chris@16 560 /// INTERNAL ONLY
Chris@16 561 ///
Chris@16 562 template<typename This, typename Fun, typename Domain>
Chris@16 563 struct virtual_member
Chris@16 564 {
Chris@16 565 typedef Domain proto_domain;
Chris@16 566 typedef typename Domain::proto_generator proto_generator;
Chris@16 567 typedef virtual_member<This, Fun, Domain> proto_derived_expr;
Chris@16 568 typedef tag::member proto_tag;
Chris@16 569 typedef list2<This &, expr<tag::terminal, term<Fun> > const &> proto_args;
Chris@16 570 typedef mpl::long_<2> proto_arity;
Chris@16 571 typedef detail::not_a_valid_type proto_address_of_hack_type_;
Chris@16 572 typedef void proto_is_expr_; /**< INTERNAL ONLY */
Chris@16 573 static const long proto_arity_c = 2;
Chris@16 574 typedef boost::proto::tag::proto_expr<proto_tag, Domain> fusion_tag;
Chris@16 575 typedef This &proto_child0;
Chris@16 576 typedef expr<tag::terminal, term<Fun> > const &proto_child1;
Chris@16 577 typedef expr<proto_tag, proto_args, proto_arity_c> proto_base_expr;
Chris@16 578 typedef basic_expr<proto_tag, proto_args, proto_arity_c> proto_grammar;
Chris@16 579 typedef void proto_is_aggregate_; /**< INTERNAL ONLY */
Chris@16 580
Chris@16 581 BOOST_PROTO_EXTENDS_ASSIGN_()
Chris@16 582 BOOST_PROTO_EXTENDS_SUBSCRIPT()
Chris@16 583
Chris@16 584 // Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
Chris@16 585 // nested preprocessor loops, use file iteration here to generate
Chris@16 586 // the operator() overloads, which is more efficient.
Chris@16 587 #define BOOST_PROTO_NO_WAVE_OUTPUT
Chris@16 588 #include <boost/proto/detail/extends_funop.hpp>
Chris@16 589 #undef BOOST_PROTO_NO_WAVE_OUTPUT
Chris@16 590
Chris@16 591 BOOST_FORCEINLINE
Chris@16 592 proto_base_expr const proto_base() const
Chris@16 593 {
Chris@16 594 proto_base_expr that = {this->child0(), this->child1()};
Chris@16 595 return that;
Chris@16 596 }
Chris@16 597
Chris@16 598 BOOST_FORCEINLINE
Chris@16 599 proto_child0 child0() const
Chris@16 600 {
Chris@16 601 using std::size_t;
Chris@16 602 return *(This *)((char *)this - BOOST_PROTO_OFFSETOF(This, proto_member_union_start_));
Chris@16 603 }
Chris@16 604
Chris@16 605 BOOST_FORCEINLINE
Chris@16 606 proto_child1 child1() const
Chris@16 607 {
Chris@16 608 static expr<tag::terminal, term<Fun>, 0> const that = {Fun()};
Chris@16 609 return that;
Chris@16 610 }
Chris@16 611 };
Chris@16 612
Chris@16 613 /// INTERNAL ONLY
Chris@16 614 ///
Chris@16 615 #define BOOST_PROTO_EXTENDS_MEMBER_(R, DOMAIN, ELEM) \
Chris@16 616 boost::proto::exprns_::virtual_member< \
Chris@16 617 proto_derived_expr \
Chris@16 618 , BOOST_PP_TUPLE_ELEM(2, 0, ELEM) \
Chris@16 619 , DOMAIN \
Chris@16 620 > BOOST_PP_TUPLE_ELEM(2, 1, ELEM); \
Chris@16 621 /**/
Chris@16 622
Chris@16 623 /// \brief For declaring virtual data members in an extension class.
Chris@16 624 ///
Chris@16 625 #define BOOST_PROTO_EXTENDS_MEMBERS_WITH_DOMAIN(SEQ, DOMAIN) \
Chris@16 626 union \
Chris@16 627 { \
Chris@16 628 char proto_member_union_start_; \
Chris@16 629 BOOST_PP_SEQ_FOR_EACH(BOOST_PROTO_EXTENDS_MEMBER_, DOMAIN, SEQ) \
Chris@16 630 }; \
Chris@16 631 /**/
Chris@16 632
Chris@16 633 /// \brief For declaring virtual data members in an extension class.
Chris@16 634 ///
Chris@16 635 #define BOOST_PROTO_EXTENDS_MEMBERS(SEQ) \
Chris@16 636 BOOST_PROTO_EXTENDS_MEMBERS_WITH_DOMAIN(SEQ, proto_domain) \
Chris@16 637 /**/
Chris@16 638
Chris@16 639 }
Chris@16 640
Chris@16 641 }}
Chris@16 642
Chris@101 643 #if defined(_MSC_VER)
Chris@16 644 # pragma warning(pop)
Chris@16 645 #endif
Chris@16 646
Chris@16 647 #endif