annotate DEPENDENCIES/generic/include/boost/proto/traits.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 traits.hpp
Chris@16 3 /// Contains definitions for child\<\>, child_c\<\>, left\<\>,
Chris@16 4 /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(),
Chris@16 5 /// value(), left() and right().
Chris@16 6 //
Chris@16 7 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 8 // Software License, Version 1.0. (See accompanying file
Chris@16 9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
Chris@16 12 #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
Chris@16 13
Chris@16 14 #include <boost/config.hpp>
Chris@16 15 #include <boost/detail/workaround.hpp>
Chris@16 16 #include <boost/preprocessor/iteration/iterate.hpp>
Chris@16 17 #include <boost/preprocessor/repetition/enum.hpp>
Chris@16 18 #include <boost/preprocessor/repetition/enum_params.hpp>
Chris@16 19 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
Chris@16 20 #include <boost/preprocessor/repetition/repeat.hpp>
Chris@16 21 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
Chris@16 22 #include <boost/preprocessor/facilities/intercept.hpp>
Chris@16 23 #include <boost/preprocessor/arithmetic/sub.hpp>
Chris@16 24 #include <boost/static_assert.hpp>
Chris@16 25 #include <boost/mpl/bool.hpp>
Chris@16 26 #include <boost/proto/detail/template_arity.hpp>
Chris@16 27 #include <boost/type_traits/is_pod.hpp>
Chris@16 28 #include <boost/type_traits/is_same.hpp>
Chris@16 29 #include <boost/type_traits/add_const.hpp>
Chris@16 30 #include <boost/proto/proto_fwd.hpp>
Chris@16 31 #include <boost/proto/args.hpp>
Chris@16 32 #include <boost/proto/domain.hpp>
Chris@16 33 #include <boost/proto/transform/pass_through.hpp>
Chris@16 34
Chris@101 35 #if defined(_MSC_VER)
Chris@16 36 # pragma warning(push)
Chris@16 37 # if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
Chris@16 38 # pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
Chris@16 39 # endif
Chris@16 40 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
Chris@16 41 #endif
Chris@16 42
Chris@16 43 namespace boost { namespace proto
Chris@16 44 {
Chris@16 45 namespace detail
Chris@16 46 {
Chris@16 47 template<typename T, typename Void = void>
Chris@16 48 struct if_vararg
Chris@16 49 {};
Chris@16 50
Chris@16 51 template<typename T>
Chris@16 52 struct if_vararg<T, typename T::proto_is_vararg_>
Chris@16 53 : T
Chris@16 54 {};
Chris@16 55
Chris@16 56 template<typename T, typename Void = void>
Chris@16 57 struct is_callable2_
Chris@16 58 : mpl::false_
Chris@16 59 {};
Chris@16 60
Chris@16 61 template<typename T>
Chris@16 62 struct is_callable2_<T, typename T::proto_is_callable_>
Chris@16 63 : mpl::true_
Chris@16 64 {};
Chris@16 65
Chris@16 66 template<typename T BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = boost::proto::detail::template_arity<T>::value)>
Chris@16 67 struct is_callable_
Chris@16 68 : is_callable2_<T>
Chris@16 69 {};
Chris@16 70
Chris@16 71 }
Chris@16 72
Chris@16 73 /// \brief Boolean metafunction which detects whether a type is
Chris@16 74 /// a callable function object type or not.
Chris@16 75 ///
Chris@16 76 /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
Chris@16 77 /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
Chris@16 78 /// callable transform or an object transform. (The former are evaluated
Chris@16 79 /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
Chris@16 80 /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is
Chris@16 81 /// a callable transform; otherwise, it is an object transform.
Chris@16 82 ///
Chris@16 83 /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt>
Chris@16 84 /// is computed as follows:
Chris@16 85 ///
Chris@16 86 /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
Chris@16 87 /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt>
Chris@16 88 /// is <tt>is_same\<YN, proto::callable\>::value</tt>.
Chris@16 89 /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
Chris@16 90 /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is
Chris@16 91 /// the case for any type that derives from \c proto::callable.)
Chris@16 92 /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false.
Chris@16 93 template<typename T>
Chris@16 94 struct is_callable
Chris@16 95 : proto::detail::is_callable_<T>
Chris@16 96 {};
Chris@16 97
Chris@16 98 /// INTERNAL ONLY
Chris@16 99 ///
Chris@16 100 template<>
Chris@16 101 struct is_callable<proto::_>
Chris@16 102 : mpl::true_
Chris@16 103 {};
Chris@16 104
Chris@16 105 /// INTERNAL ONLY
Chris@16 106 ///
Chris@16 107 template<>
Chris@16 108 struct is_callable<proto::callable>
Chris@16 109 : mpl::false_
Chris@16 110 {};
Chris@16 111
Chris@16 112 /// INTERNAL ONLY
Chris@16 113 ///
Chris@16 114 template<typename PrimitiveTransform, typename X>
Chris@16 115 struct is_callable<proto::transform<PrimitiveTransform, X> >
Chris@16 116 : mpl::false_
Chris@16 117 {};
Chris@16 118
Chris@16 119 #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0)
Chris@16 120 // work around GCC bug
Chris@16 121 template<typename Tag, typename Args, long N>
Chris@16 122 struct is_callable<proto::expr<Tag, Args, N> >
Chris@16 123 : mpl::false_
Chris@16 124 {};
Chris@16 125
Chris@16 126 // work around GCC bug
Chris@16 127 template<typename Tag, typename Args, long N>
Chris@16 128 struct is_callable<proto::basic_expr<Tag, Args, N> >
Chris@16 129 : mpl::false_
Chris@16 130 {};
Chris@16 131 #endif
Chris@16 132
Chris@16 133 namespace detail
Chris@16 134 {
Chris@16 135 template<typename T, typename Void /*= void*/>
Chris@16 136 struct is_transform_
Chris@16 137 : mpl::false_
Chris@16 138 {};
Chris@16 139
Chris@16 140 template<typename T>
Chris@16 141 struct is_transform_<T, typename T::proto_is_transform_>
Chris@16 142 : mpl::true_
Chris@16 143 {};
Chris@16 144 }
Chris@16 145
Chris@16 146 /// \brief Boolean metafunction which detects whether a type is
Chris@16 147 /// a PrimitiveTransform type or not.
Chris@16 148 ///
Chris@16 149 /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform
Chris@16 150 /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>,
Chris@16 151 /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data
Chris@16 152 /// parameters (as needed).
Chris@16 153 ///
Chris@16 154 /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt>
Chris@16 155 /// is computed as follows:
Chris@16 156 ///
Chris@16 157 /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef
Chris@16 158 /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is
Chris@16 159 /// the case for any type that derives from an instantiation of \c proto::transform.)
Chris@16 160 /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false.
Chris@16 161 template<typename T>
Chris@16 162 struct is_transform
Chris@16 163 : proto::detail::is_transform_<T>
Chris@16 164 {};
Chris@16 165
Chris@16 166 namespace detail
Chris@16 167 {
Chris@16 168 template<typename T, typename Void /*= void*/>
Chris@16 169 struct is_aggregate_
Chris@16 170 : is_pod<T>
Chris@16 171 {};
Chris@16 172
Chris@16 173 template<typename Tag, typename Args, long N>
Chris@16 174 struct is_aggregate_<proto::expr<Tag, Args, N>, void>
Chris@16 175 : mpl::true_
Chris@16 176 {};
Chris@16 177
Chris@16 178 template<typename Tag, typename Args, long N>
Chris@16 179 struct is_aggregate_<proto::basic_expr<Tag, Args, N>, void>
Chris@16 180 : mpl::true_
Chris@16 181 {};
Chris@16 182
Chris@16 183 template<typename T>
Chris@16 184 struct is_aggregate_<T, typename T::proto_is_aggregate_>
Chris@16 185 : mpl::true_
Chris@16 186 {};
Chris@16 187 }
Chris@16 188
Chris@16 189 /// \brief A Boolean metafunction that indicates whether a type requires
Chris@16 190 /// aggregate initialization.
Chris@16 191 ///
Chris@16 192 /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
Chris@16 193 /// to determine how to construct an object of some type \c T, given some
Chris@16 194 /// initialization arguments <tt>a0,a1,...aN</tt>.
Chris@16 195 /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of
Chris@16 196 /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
Chris@16 197 /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
Chris@16 198 template<typename T>
Chris@16 199 struct is_aggregate
Chris@16 200 : proto::detail::is_aggregate_<T>
Chris@16 201 {};
Chris@16 202
Chris@16 203 /// \brief A Boolean metafunction that indicates whether a given
Chris@16 204 /// type \c T is a Proto expression type.
Chris@16 205 ///
Chris@16 206 /// If \c T has a nested type \c proto_is_expr_ that is a typedef
Chris@16 207 /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
Chris@16 208 /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
Chris@16 209 /// from <tt>proto::extends\<\></tt> or that uses the
Chris@16 210 /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
Chris@16 211 /// <tt>is_expr\<T\>::value</tt> is \c false.
Chris@16 212 template<typename T, typename Void /* = void*/>
Chris@16 213 struct is_expr
Chris@16 214 : mpl::false_
Chris@16 215 {};
Chris@16 216
Chris@16 217 /// \brief A Boolean metafunction that indicates whether a given
Chris@16 218 /// type \c T is a Proto expression type.
Chris@16 219 ///
Chris@16 220 /// If \c T has a nested type \c proto_is_expr_ that is a typedef
Chris@16 221 /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
Chris@16 222 /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
Chris@16 223 /// from <tt>proto::extends\<\></tt> or that uses the
Chris@16 224 /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
Chris@16 225 /// <tt>is_expr\<T\>::value</tt> is \c false.
Chris@16 226 template<typename T>
Chris@16 227 struct is_expr<T, typename T::proto_is_expr_>
Chris@16 228 : mpl::true_
Chris@16 229 {};
Chris@16 230
Chris@16 231 template<typename T>
Chris@16 232 struct is_expr<T &, void>
Chris@16 233 : is_expr<T>
Chris@16 234 {};
Chris@16 235
Chris@16 236 /// \brief A metafunction that returns the tag type of a
Chris@16 237 /// Proto expression.
Chris@16 238 template<typename Expr>
Chris@16 239 struct tag_of
Chris@16 240 {
Chris@16 241 typedef typename Expr::proto_tag type;
Chris@16 242 };
Chris@16 243
Chris@16 244 template<typename Expr>
Chris@16 245 struct tag_of<Expr &>
Chris@16 246 {
Chris@16 247 typedef typename Expr::proto_tag type;
Chris@16 248 };
Chris@16 249
Chris@16 250 /// \brief A metafunction that returns the arity of a
Chris@16 251 /// Proto expression.
Chris@16 252 template<typename Expr>
Chris@16 253 struct arity_of
Chris@16 254 : Expr::proto_arity
Chris@16 255 {};
Chris@16 256
Chris@16 257 template<typename Expr>
Chris@16 258 struct arity_of<Expr &>
Chris@16 259 : Expr::proto_arity
Chris@16 260 {};
Chris@16 261
Chris@16 262 namespace result_of
Chris@16 263 {
Chris@16 264 /// \brief A metafunction that computes the return type of the \c as_expr()
Chris@16 265 /// function.
Chris@16 266 template<typename T, typename Domain /*= default_domain*/>
Chris@16 267 struct as_expr
Chris@16 268 {
Chris@16 269 typedef typename Domain::template as_expr<T>::result_type type;
Chris@16 270 };
Chris@16 271
Chris@16 272 /// \brief A metafunction that computes the return type of the \c as_child()
Chris@16 273 /// function.
Chris@16 274 template<typename T, typename Domain /*= default_domain*/>
Chris@16 275 struct as_child
Chris@16 276 {
Chris@16 277 typedef typename Domain::template as_child<T>::result_type type;
Chris@16 278 };
Chris@16 279
Chris@16 280 /// \brief A metafunction that returns the type of the Nth child
Chris@16 281 /// of a Proto expression, where N is an MPL Integral Constant.
Chris@16 282 ///
Chris@16 283 /// <tt>result_of::child\<Expr, N\></tt> is equivalent to
Chris@16 284 /// <tt>result_of::child_c\<Expr, N::value\></tt>.
Chris@16 285 template<typename Expr, typename N /* = mpl::long_<0>*/>
Chris@16 286 struct child
Chris@16 287 : child_c<Expr, N::value>
Chris@16 288 {};
Chris@16 289
Chris@16 290 /// \brief A metafunction that returns the type of the value
Chris@16 291 /// of a terminal Proto expression.
Chris@16 292 ///
Chris@16 293 template<typename Expr>
Chris@16 294 struct value
Chris@16 295 {
Chris@16 296 /// Verify that we are actually operating on a terminal
Chris@16 297 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
Chris@16 298
Chris@16 299 /// The raw type of the Nth child as it is stored within
Chris@16 300 /// \c Expr. This may be a value or a reference
Chris@16 301 typedef typename Expr::proto_child0 value_type;
Chris@16 302
Chris@16 303 /// The "value" type of the child, suitable for storage by value,
Chris@16 304 /// computed as follows:
Chris@16 305 /// \li <tt>T const(&)[N]</tt> becomes <tt>T[N]</tt>
Chris@16 306 /// \li <tt>T[N]</tt> becomes <tt>T[N]</tt>
Chris@16 307 /// \li <tt>T(&)[N]</tt> becomes <tt>T[N]</tt>
Chris@16 308 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
Chris@16 309 /// \li <tt>T const &</tt> becomes <tt>T</tt>
Chris@16 310 /// \li <tt>T &</tt> becomes <tt>T</tt>
Chris@16 311 /// \li <tt>T</tt> becomes <tt>T</tt>
Chris@16 312 typedef typename detail::term_traits<typename Expr::proto_child0>::value_type type;
Chris@16 313 };
Chris@16 314
Chris@16 315 template<typename Expr>
Chris@16 316 struct value<Expr &>
Chris@16 317 {
Chris@16 318 /// Verify that we are actually operating on a terminal
Chris@16 319 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
Chris@16 320
Chris@16 321 /// The raw type of the Nth child as it is stored within
Chris@16 322 /// \c Expr. This may be a value or a reference
Chris@16 323 typedef typename Expr::proto_child0 value_type;
Chris@16 324
Chris@16 325 /// The "reference" type of the child, suitable for storage by
Chris@16 326 /// reference, computed as follows:
Chris@16 327 /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
Chris@16 328 /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
Chris@16 329 /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
Chris@16 330 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
Chris@16 331 /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
Chris@16 332 /// \li <tt>T &</tt> becomes <tt>T &</tt>
Chris@16 333 /// \li <tt>T</tt> becomes <tt>T &</tt>
Chris@16 334 typedef typename detail::term_traits<typename Expr::proto_child0>::reference type;
Chris@16 335 };
Chris@16 336
Chris@16 337 template<typename Expr>
Chris@16 338 struct value<Expr const &>
Chris@16 339 {
Chris@16 340 /// Verify that we are actually operating on a terminal
Chris@16 341 BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
Chris@16 342
Chris@16 343 /// The raw type of the Nth child as it is stored within
Chris@16 344 /// \c Expr. This may be a value or a reference
Chris@16 345 typedef typename Expr::proto_child0 value_type;
Chris@16 346
Chris@16 347 /// The "const reference" type of the child, suitable for storage by
Chris@16 348 /// const reference, computed as follows:
Chris@16 349 /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
Chris@16 350 /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt>
Chris@16 351 /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
Chris@16 352 /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
Chris@16 353 /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
Chris@16 354 /// \li <tt>T &</tt> becomes <tt>T &</tt>
Chris@16 355 /// \li <tt>T</tt> becomes <tt>T const &</tt>
Chris@16 356 typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type;
Chris@16 357 };
Chris@16 358
Chris@16 359 /// \brief A metafunction that returns the type of the left child
Chris@16 360 /// of a binary Proto expression.
Chris@16 361 ///
Chris@16 362 /// <tt>result_of::left\<Expr\></tt> is equivalent to
Chris@16 363 /// <tt>result_of::child_c\<Expr, 0\></tt>.
Chris@16 364 template<typename Expr>
Chris@16 365 struct left
Chris@16 366 : child_c<Expr, 0>
Chris@16 367 {};
Chris@16 368
Chris@16 369 /// \brief A metafunction that returns the type of the right child
Chris@16 370 /// of a binary Proto expression.
Chris@16 371 ///
Chris@16 372 /// <tt>result_of::right\<Expr\></tt> is equivalent to
Chris@16 373 /// <tt>result_of::child_c\<Expr, 1\></tt>.
Chris@16 374 template<typename Expr>
Chris@16 375 struct right
Chris@16 376 : child_c<Expr, 1>
Chris@16 377 {};
Chris@16 378
Chris@16 379 } // namespace result_of
Chris@16 380
Chris@16 381 /// \brief A metafunction for generating terminal expression types,
Chris@16 382 /// a grammar element for matching terminal expressions, and a
Chris@16 383 /// PrimitiveTransform that returns the current expression unchanged.
Chris@16 384 template<typename T>
Chris@16 385 struct terminal
Chris@16 386 : proto::transform<terminal<T>, int>
Chris@16 387 {
Chris@16 388 typedef proto::expr<proto::tag::terminal, term<T>, 0> type;
Chris@16 389 typedef proto::basic_expr<proto::tag::terminal, term<T>, 0> proto_grammar;
Chris@16 390
Chris@16 391 template<typename Expr, typename State, typename Data>
Chris@16 392 struct impl : transform_impl<Expr, State, Data>
Chris@16 393 {
Chris@16 394 typedef Expr result_type;
Chris@16 395
Chris@16 396 /// \param e The current expression
Chris@16 397 /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true.
Chris@16 398 /// \return \c e
Chris@16 399 /// \throw nothrow
Chris@16 400 BOOST_FORCEINLINE
Chris@16 401 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
Chris@16 402 operator ()(
Chris@16 403 typename impl::expr_param e
Chris@16 404 , typename impl::state_param
Chris@16 405 , typename impl::data_param
Chris@16 406 ) const
Chris@16 407 {
Chris@16 408 return e;
Chris@16 409 }
Chris@16 410 };
Chris@16 411
Chris@16 412 /// INTERNAL ONLY
Chris@16 413 typedef proto::tag::terminal proto_tag;
Chris@16 414 /// INTERNAL ONLY
Chris@16 415 typedef T proto_child0;
Chris@16 416 };
Chris@16 417
Chris@16 418 /// \brief A metafunction for generating ternary conditional expression types,
Chris@16 419 /// a grammar element for matching ternary conditional expressions, and a
Chris@16 420 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
Chris@16 421 /// transform.
Chris@16 422 template<typename T, typename U, typename V>
Chris@16 423 struct if_else_
Chris@16 424 : proto::transform<if_else_<T, U, V>, int>
Chris@16 425 {
Chris@16 426 typedef proto::expr<proto::tag::if_else_, list3<T, U, V>, 3> type;
Chris@16 427 typedef proto::basic_expr<proto::tag::if_else_, list3<T, U, V>, 3> proto_grammar;
Chris@16 428
Chris@16 429 template<typename Expr, typename State, typename Data>
Chris@16 430 struct impl
Chris@16 431 : detail::pass_through_impl<if_else_, deduce_domain, Expr, State, Data>
Chris@16 432 {};
Chris@16 433
Chris@16 434 /// INTERNAL ONLY
Chris@16 435 typedef proto::tag::if_else_ proto_tag;
Chris@16 436 /// INTERNAL ONLY
Chris@16 437 typedef T proto_child0;
Chris@16 438 /// INTERNAL ONLY
Chris@16 439 typedef U proto_child1;
Chris@16 440 /// INTERNAL ONLY
Chris@16 441 typedef V proto_child2;
Chris@16 442 };
Chris@16 443
Chris@16 444 /// \brief A metafunction for generating nullary expression types with a
Chris@16 445 /// specified tag type,
Chris@16 446 /// a grammar element for matching nullary expressions, and a
Chris@16 447 /// PrimitiveTransform that returns the current expression unchanged.
Chris@16 448 ///
Chris@16 449 /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any
Chris@16 450 /// nullary expression.
Chris@16 451 template<typename Tag, typename T>
Chris@16 452 struct nullary_expr
Chris@16 453 : proto::transform<nullary_expr<Tag, T>, int>
Chris@16 454 {
Chris@16 455 typedef proto::expr<Tag, term<T>, 0> type;
Chris@16 456 typedef proto::basic_expr<Tag, term<T>, 0> proto_grammar;
Chris@16 457
Chris@16 458 template<typename Expr, typename State, typename Data>
Chris@16 459 struct impl : transform_impl<Expr, State, Data>
Chris@16 460 {
Chris@16 461 typedef Expr result_type;
Chris@16 462
Chris@16 463 /// \param e The current expression
Chris@16 464 /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true.
Chris@16 465 /// \return \c e
Chris@16 466 /// \throw nothrow
Chris@16 467 BOOST_FORCEINLINE
Chris@16 468 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
Chris@16 469 operator ()(
Chris@16 470 typename impl::expr_param e
Chris@16 471 , typename impl::state_param
Chris@16 472 , typename impl::data_param
Chris@16 473 ) const
Chris@16 474 {
Chris@16 475 return e;
Chris@16 476 }
Chris@16 477 };
Chris@16 478
Chris@16 479 /// INTERNAL ONLY
Chris@16 480 typedef Tag proto_tag;
Chris@16 481 /// INTERNAL ONLY
Chris@16 482 typedef T proto_child0;
Chris@16 483 };
Chris@16 484
Chris@16 485 /// \brief A metafunction for generating unary expression types with a
Chris@16 486 /// specified tag type,
Chris@16 487 /// a grammar element for matching unary expressions, and a
Chris@16 488 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
Chris@16 489 /// transform.
Chris@16 490 ///
Chris@16 491 /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
Chris@16 492 /// unary expression.
Chris@16 493 template<typename Tag, typename T>
Chris@16 494 struct unary_expr
Chris@16 495 : proto::transform<unary_expr<Tag, T>, int>
Chris@16 496 {
Chris@16 497 typedef proto::expr<Tag, list1<T>, 1> type;
Chris@16 498 typedef proto::basic_expr<Tag, list1<T>, 1> proto_grammar;
Chris@16 499
Chris@16 500 template<typename Expr, typename State, typename Data>
Chris@16 501 struct impl
Chris@16 502 : detail::pass_through_impl<unary_expr, deduce_domain, Expr, State, Data>
Chris@16 503 {};
Chris@16 504
Chris@16 505 /// INTERNAL ONLY
Chris@16 506 typedef Tag proto_tag;
Chris@16 507 /// INTERNAL ONLY
Chris@16 508 typedef T proto_child0;
Chris@16 509 };
Chris@16 510
Chris@16 511 /// \brief A metafunction for generating binary expression types with a
Chris@16 512 /// specified tag type,
Chris@16 513 /// a grammar element for matching binary expressions, and a
Chris@16 514 /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
Chris@16 515 /// transform.
Chris@16 516 ///
Chris@16 517 /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
Chris@16 518 /// binary expression.
Chris@16 519 template<typename Tag, typename T, typename U>
Chris@16 520 struct binary_expr
Chris@16 521 : proto::transform<binary_expr<Tag, T, U>, int>
Chris@16 522 {
Chris@16 523 typedef proto::expr<Tag, list2<T, U>, 2> type;
Chris@16 524 typedef proto::basic_expr<Tag, list2<T, U>, 2> proto_grammar;
Chris@16 525
Chris@16 526 template<typename Expr, typename State, typename Data>
Chris@16 527 struct impl
Chris@16 528 : detail::pass_through_impl<binary_expr, deduce_domain, Expr, State, Data>
Chris@16 529 {};
Chris@16 530
Chris@16 531 /// INTERNAL ONLY
Chris@16 532 typedef Tag proto_tag;
Chris@16 533 /// INTERNAL ONLY
Chris@16 534 typedef T proto_child0;
Chris@16 535 /// INTERNAL ONLY
Chris@16 536 typedef U proto_child1;
Chris@16 537 };
Chris@16 538
Chris@16 539 #define BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(Op) \
Chris@16 540 template<typename T> \
Chris@16 541 struct Op \
Chris@16 542 : proto::transform<Op<T>, int> \
Chris@16 543 { \
Chris@16 544 typedef proto::expr<proto::tag::Op, list1<T>, 1> type; \
Chris@16 545 typedef proto::basic_expr<proto::tag::Op, list1<T>, 1> proto_grammar; \
Chris@16 546 \
Chris@16 547 template<typename Expr, typename State, typename Data> \
Chris@16 548 struct impl \
Chris@16 549 : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \
Chris@16 550 {}; \
Chris@16 551 \
Chris@16 552 typedef proto::tag::Op proto_tag; \
Chris@16 553 typedef T proto_child0; \
Chris@16 554 }; \
Chris@16 555 /**/
Chris@16 556
Chris@16 557 #define BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(Op) \
Chris@16 558 template<typename T, typename U> \
Chris@16 559 struct Op \
Chris@16 560 : proto::transform<Op<T, U>, int> \
Chris@16 561 { \
Chris@16 562 typedef proto::expr<proto::tag::Op, list2<T, U>, 2> type; \
Chris@16 563 typedef proto::basic_expr<proto::tag::Op, list2<T, U>, 2> proto_grammar; \
Chris@16 564 \
Chris@16 565 template<typename Expr, typename State, typename Data> \
Chris@16 566 struct impl \
Chris@16 567 : detail::pass_through_impl<Op, deduce_domain, Expr, State, Data> \
Chris@16 568 {}; \
Chris@16 569 \
Chris@16 570 typedef proto::tag::Op proto_tag; \
Chris@16 571 typedef T proto_child0; \
Chris@16 572 typedef U proto_child1; \
Chris@16 573 }; \
Chris@16 574 /**/
Chris@16 575
Chris@16 576 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(unary_plus)
Chris@16 577 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(negate)
Chris@16 578 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(dereference)
Chris@16 579 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(complement)
Chris@16 580 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(address_of)
Chris@16 581 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(logical_not)
Chris@16 582 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_inc)
Chris@16 583 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_dec)
Chris@16 584 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_inc)
Chris@16 585 BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_dec)
Chris@16 586
Chris@16 587 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left)
Chris@16 588 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right)
Chris@16 589 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies)
Chris@16 590 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides)
Chris@16 591 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus)
Chris@16 592 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus)
Chris@16 593 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus)
Chris@16 594 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less)
Chris@16 595 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater)
Chris@16 596 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less_equal)
Chris@16 597 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater_equal)
Chris@16 598 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(equal_to)
Chris@16 599 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(not_equal_to)
Chris@16 600 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_or)
Chris@16 601 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_and)
Chris@16 602 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or)
Chris@16 603 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and)
Chris@16 604 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor)
Chris@16 605 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(comma)
Chris@16 606 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(mem_ptr)
Chris@16 607 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(assign)
Chris@16 608 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left_assign)
Chris@16 609 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right_assign)
Chris@16 610 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies_assign)
Chris@16 611 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides_assign)
Chris@16 612 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus_assign)
Chris@16 613 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus_assign)
Chris@16 614 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus_assign)
Chris@16 615 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign)
Chris@16 616 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign)
Chris@16 617 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign)
Chris@16 618 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(subscript)
Chris@16 619 BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(member)
Chris@16 620
Chris@16 621 #undef BOOST_PROTO_DEFINE_UNARY_METAFUNCTION
Chris@16 622 #undef BOOST_PROTO_DEFINE_BINARY_METAFUNCTION
Chris@16 623
Chris@16 624 #include <boost/proto/detail/traits.hpp>
Chris@16 625
Chris@16 626 namespace functional
Chris@16 627 {
Chris@16 628 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 629 /// equivalent to the \c as_expr() function.
Chris@16 630 template<typename Domain /* = default_domain*/>
Chris@16 631 struct as_expr
Chris@16 632 {
Chris@16 633 BOOST_PROTO_CALLABLE()
Chris@16 634
Chris@16 635 template<typename Sig>
Chris@16 636 struct result;
Chris@16 637
Chris@16 638 template<typename This, typename T>
Chris@16 639 struct result<This(T)>
Chris@16 640 {
Chris@16 641 typedef typename Domain::template as_expr<T>::result_type type;
Chris@16 642 };
Chris@16 643
Chris@16 644 template<typename This, typename T>
Chris@16 645 struct result<This(T &)>
Chris@16 646 {
Chris@16 647 typedef typename Domain::template as_expr<T>::result_type type;
Chris@16 648 };
Chris@16 649
Chris@16 650 /// \brief Wrap an object in a Proto terminal if it isn't a
Chris@16 651 /// Proto expression already.
Chris@16 652 /// \param t The object to wrap.
Chris@16 653 /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
Chris@16 654 template<typename T>
Chris@16 655 BOOST_FORCEINLINE
Chris@16 656 typename add_const<typename result<as_expr(T &)>::type>::type
Chris@16 657 operator ()(T &t) const
Chris@16 658 {
Chris@16 659 return typename Domain::template as_expr<T>()(t);
Chris@16 660 }
Chris@16 661
Chris@16 662 /// \overload
Chris@16 663 ///
Chris@16 664 template<typename T>
Chris@16 665 BOOST_FORCEINLINE
Chris@16 666 typename add_const<typename result<as_expr(T const &)>::type>::type
Chris@16 667 operator ()(T const &t) const
Chris@16 668 {
Chris@16 669 return typename Domain::template as_expr<T const>()(t);
Chris@16 670 }
Chris@16 671
Chris@16 672 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
Chris@16 673 template<typename T, std::size_t N_>
Chris@16 674 BOOST_FORCEINLINE
Chris@16 675 typename add_const<typename result<as_expr(T (&)[N_])>::type>::type
Chris@16 676 operator ()(T (&t)[N_]) const
Chris@16 677 {
Chris@16 678 return typename Domain::template as_expr<T[N_]>()(t);
Chris@16 679 }
Chris@16 680
Chris@16 681 template<typename T, std::size_t N_>
Chris@16 682 BOOST_FORCEINLINE
Chris@16 683 typename add_const<typename result<as_expr(T const (&)[N_])>::type>::type
Chris@16 684 operator ()(T const (&t)[N_]) const
Chris@16 685 {
Chris@16 686 return typename Domain::template as_expr<T const[N_]>()(t);
Chris@16 687 }
Chris@16 688 #endif
Chris@16 689 };
Chris@16 690
Chris@16 691 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 692 /// equivalent to the \c as_child() function.
Chris@16 693 template<typename Domain /* = default_domain*/>
Chris@16 694 struct as_child
Chris@16 695 {
Chris@16 696 BOOST_PROTO_CALLABLE()
Chris@16 697
Chris@16 698 template<typename Sig>
Chris@16 699 struct result;
Chris@16 700
Chris@16 701 template<typename This, typename T>
Chris@16 702 struct result<This(T)>
Chris@16 703 {
Chris@16 704 typedef typename Domain::template as_child<T>::result_type type;
Chris@16 705 };
Chris@16 706
Chris@16 707 template<typename This, typename T>
Chris@16 708 struct result<This(T &)>
Chris@16 709 {
Chris@16 710 typedef typename Domain::template as_child<T>::result_type type;
Chris@16 711 };
Chris@16 712
Chris@16 713 /// \brief Wrap an object in a Proto terminal if it isn't a
Chris@16 714 /// Proto expression already.
Chris@16 715 /// \param t The object to wrap.
Chris@16 716 /// \return <tt>proto::as_child\<Domain\>(t)</tt>
Chris@16 717 template<typename T>
Chris@16 718 BOOST_FORCEINLINE
Chris@16 719 typename add_const<typename result<as_child(T &)>::type>::type
Chris@16 720 operator ()(T &t) const
Chris@16 721 {
Chris@16 722 return typename Domain::template as_child<T>()(t);
Chris@16 723 }
Chris@16 724
Chris@16 725 /// \overload
Chris@16 726 ///
Chris@16 727 template<typename T>
Chris@16 728 BOOST_FORCEINLINE
Chris@16 729 typename add_const<typename result<as_child(T const &)>::type>::type
Chris@16 730 operator ()(T const &t) const
Chris@16 731 {
Chris@16 732 return typename Domain::template as_child<T const>()(t);
Chris@16 733 }
Chris@16 734 };
Chris@16 735
Chris@16 736 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 737 /// equivalent to the \c child_c() function.
Chris@16 738 template<long N>
Chris@16 739 struct child_c
Chris@16 740 {
Chris@16 741 BOOST_PROTO_CALLABLE()
Chris@16 742
Chris@16 743 template<typename Sig>
Chris@16 744 struct result;
Chris@16 745
Chris@16 746 template<typename This, typename Expr>
Chris@16 747 struct result<This(Expr)>
Chris@16 748 {
Chris@16 749 typedef typename result_of::child_c<Expr, N>::type type;
Chris@16 750 };
Chris@16 751
Chris@16 752 /// \brief Return the Nth child of the given expression.
Chris@16 753 /// \param expr The expression node.
Chris@16 754 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
Chris@16 755 /// \pre <tt>N \< Expr::proto_arity::value</tt>
Chris@16 756 /// \return <tt>proto::child_c\<N\>(expr)</tt>
Chris@16 757 /// \throw nothrow
Chris@16 758 template<typename Expr>
Chris@16 759 BOOST_FORCEINLINE
Chris@16 760 typename result_of::child_c<Expr &, N>::type
Chris@16 761 operator ()(Expr &e) const
Chris@16 762 {
Chris@16 763 return result_of::child_c<Expr &, N>::call(e);
Chris@16 764 }
Chris@16 765
Chris@16 766 /// \overload
Chris@16 767 ///
Chris@16 768 template<typename Expr>
Chris@16 769 BOOST_FORCEINLINE
Chris@16 770 typename result_of::child_c<Expr const &, N>::type
Chris@16 771 operator ()(Expr const &e) const
Chris@16 772 {
Chris@16 773 return result_of::child_c<Expr const &, N>::call(e);
Chris@16 774 }
Chris@16 775 };
Chris@16 776
Chris@16 777 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 778 /// equivalent to the \c child() function.
Chris@16 779 ///
Chris@16 780 /// A callable PolymorphicFunctionObject that is
Chris@16 781 /// equivalent to the \c child() function. \c N is required
Chris@16 782 /// to be an MPL Integral Constant.
Chris@16 783 template<typename N /* = mpl::long_<0>*/>
Chris@16 784 struct child
Chris@16 785 {
Chris@16 786 BOOST_PROTO_CALLABLE()
Chris@16 787
Chris@16 788 template<typename Sig>
Chris@16 789 struct result;
Chris@16 790
Chris@16 791 template<typename This, typename Expr>
Chris@16 792 struct result<This(Expr)>
Chris@16 793 {
Chris@16 794 typedef typename result_of::child<Expr, N>::type type;
Chris@16 795 };
Chris@16 796
Chris@16 797 /// \brief Return the Nth child of the given expression.
Chris@16 798 /// \param expr The expression node.
Chris@16 799 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
Chris@16 800 /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
Chris@16 801 /// \return <tt>proto::child\<N\>(expr)</tt>
Chris@16 802 /// \throw nothrow
Chris@16 803 template<typename Expr>
Chris@16 804 BOOST_FORCEINLINE
Chris@16 805 typename result_of::child<Expr &, N>::type
Chris@16 806 operator ()(Expr &e) const
Chris@16 807 {
Chris@16 808 return result_of::child<Expr &, N>::call(e);
Chris@16 809 }
Chris@16 810
Chris@16 811 /// \overload
Chris@16 812 ///
Chris@16 813 template<typename Expr>
Chris@16 814 BOOST_FORCEINLINE
Chris@16 815 typename result_of::child<Expr const &, N>::type
Chris@16 816 operator ()(Expr const &e) const
Chris@16 817 {
Chris@16 818 return result_of::child<Expr const &, N>::call(e);
Chris@16 819 }
Chris@16 820 };
Chris@16 821
Chris@16 822 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 823 /// equivalent to the \c value() function.
Chris@16 824 struct value
Chris@16 825 {
Chris@16 826 BOOST_PROTO_CALLABLE()
Chris@16 827
Chris@16 828 template<typename Sig>
Chris@16 829 struct result;
Chris@16 830
Chris@16 831 template<typename This, typename Expr>
Chris@16 832 struct result<This(Expr)>
Chris@16 833 {
Chris@16 834 typedef typename result_of::value<Expr>::type type;
Chris@16 835 };
Chris@16 836
Chris@16 837 /// \brief Return the value of the given terminal expression.
Chris@16 838 /// \param expr The terminal expression node.
Chris@16 839 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
Chris@16 840 /// \pre <tt>0 == Expr::proto_arity::value</tt>
Chris@16 841 /// \return <tt>proto::value(expr)</tt>
Chris@16 842 /// \throw nothrow
Chris@16 843 template<typename Expr>
Chris@16 844 BOOST_FORCEINLINE
Chris@16 845 typename result_of::value<Expr &>::type
Chris@16 846 operator ()(Expr &e) const
Chris@16 847 {
Chris@16 848 return e.proto_base().child0;
Chris@16 849 }
Chris@16 850
Chris@16 851 /// \overload
Chris@16 852 ///
Chris@16 853 template<typename Expr>
Chris@16 854 BOOST_FORCEINLINE
Chris@16 855 typename result_of::value<Expr const &>::type
Chris@16 856 operator ()(Expr const &e) const
Chris@16 857 {
Chris@16 858 return e.proto_base().child0;
Chris@16 859 }
Chris@16 860 };
Chris@16 861
Chris@16 862 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 863 /// equivalent to the \c left() function.
Chris@16 864 struct left
Chris@16 865 {
Chris@16 866 BOOST_PROTO_CALLABLE()
Chris@16 867
Chris@16 868 template<typename Sig>
Chris@16 869 struct result;
Chris@16 870
Chris@16 871 template<typename This, typename Expr>
Chris@16 872 struct result<This(Expr)>
Chris@16 873 {
Chris@16 874 typedef typename result_of::left<Expr>::type type;
Chris@16 875 };
Chris@16 876
Chris@16 877 /// \brief Return the left child of the given binary expression.
Chris@16 878 /// \param expr The expression node.
Chris@16 879 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
Chris@16 880 /// \pre <tt>2 == Expr::proto_arity::value</tt>
Chris@16 881 /// \return <tt>proto::left(expr)</tt>
Chris@16 882 /// \throw nothrow
Chris@16 883 template<typename Expr>
Chris@16 884 BOOST_FORCEINLINE
Chris@16 885 typename result_of::left<Expr &>::type
Chris@16 886 operator ()(Expr &e) const
Chris@16 887 {
Chris@16 888 return e.proto_base().child0;
Chris@16 889 }
Chris@16 890
Chris@16 891 /// \overload
Chris@16 892 ///
Chris@16 893 template<typename Expr>
Chris@16 894 BOOST_FORCEINLINE
Chris@16 895 typename result_of::left<Expr const &>::type
Chris@16 896 operator ()(Expr const &e) const
Chris@16 897 {
Chris@16 898 return e.proto_base().child0;
Chris@16 899 }
Chris@16 900 };
Chris@16 901
Chris@16 902 /// \brief A callable PolymorphicFunctionObject that is
Chris@16 903 /// equivalent to the \c right() function.
Chris@16 904 struct right
Chris@16 905 {
Chris@16 906 BOOST_PROTO_CALLABLE()
Chris@16 907
Chris@16 908 template<typename Sig>
Chris@16 909 struct result;
Chris@16 910
Chris@16 911 template<typename This, typename Expr>
Chris@16 912 struct result<This(Expr)>
Chris@16 913 {
Chris@16 914 typedef typename result_of::right<Expr>::type type;
Chris@16 915 };
Chris@16 916
Chris@16 917 /// \brief Return the right child of the given binary expression.
Chris@16 918 /// \param expr The expression node.
Chris@16 919 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
Chris@16 920 /// \pre <tt>2 == Expr::proto_arity::value</tt>
Chris@16 921 /// \return <tt>proto::right(expr)</tt>
Chris@16 922 /// \throw nothrow
Chris@16 923 template<typename Expr>
Chris@16 924 BOOST_FORCEINLINE
Chris@16 925 typename result_of::right<Expr &>::type
Chris@16 926 operator ()(Expr &e) const
Chris@16 927 {
Chris@16 928 return e.proto_base().child1;
Chris@16 929 }
Chris@16 930
Chris@16 931 template<typename Expr>
Chris@16 932 BOOST_FORCEINLINE
Chris@16 933 typename result_of::right<Expr const &>::type
Chris@16 934 operator ()(Expr const &e) const
Chris@16 935 {
Chris@16 936 return e.proto_base().child1;
Chris@16 937 }
Chris@16 938 };
Chris@16 939
Chris@16 940 }
Chris@16 941
Chris@16 942 /// \brief A function that wraps non-Proto expression types in Proto
Chris@16 943 /// terminals and leaves Proto expression types alone.
Chris@16 944 ///
Chris@16 945 /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
Chris@16 946 /// they are not Proto expression types already. Non-Proto types are
Chris@16 947 /// held by value, if possible. Types which are already Proto types are
Chris@16 948 /// left alone and returned by reference.
Chris@16 949 ///
Chris@16 950 /// This function can be called either with an explicitly specified
Chris@16 951 /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
Chris@16 952 /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
Chris@16 953 /// specified, \c default_domain is assumed.
Chris@16 954 ///
Chris@16 955 /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
Chris@16 956 /// returned unmodified, by reference. Otherwise, the argument is wrapped
Chris@16 957 /// in a Proto terminal expression node according to the following rules.
Chris@16 958 /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
Chris@16 959 /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
Chris@16 960 /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>.
Chris@16 961 ///
Chris@16 962 /// \param t The object to wrap.
Chris@16 963 template<typename T>
Chris@16 964 BOOST_FORCEINLINE
Chris@16 965 typename add_const<typename result_of::as_expr<T, default_domain>::type>::type
Chris@16 966 as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
Chris@16 967 {
Chris@16 968 return default_domain::as_expr<T>()(t);
Chris@16 969 }
Chris@16 970
Chris@16 971 /// \overload
Chris@16 972 ///
Chris@16 973 template<typename T>
Chris@16 974 BOOST_FORCEINLINE
Chris@16 975 typename add_const<typename result_of::as_expr<T const, default_domain>::type>::type
Chris@16 976 as_expr(T const &t)
Chris@16 977 {
Chris@16 978 return default_domain::as_expr<T const>()(t);
Chris@16 979 }
Chris@16 980
Chris@16 981 /// \overload
Chris@16 982 ///
Chris@16 983 template<typename Domain, typename T>
Chris@16 984 BOOST_FORCEINLINE
Chris@16 985 typename add_const<typename result_of::as_expr<T, Domain>::type>::type
Chris@16 986 as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
Chris@16 987 {
Chris@16 988 return typename Domain::template as_expr<T>()(t);
Chris@16 989 }
Chris@16 990
Chris@16 991 /// \overload
Chris@16 992 ///
Chris@16 993 template<typename Domain, typename T>
Chris@16 994 BOOST_FORCEINLINE
Chris@16 995 typename add_const<typename result_of::as_expr<T const, Domain>::type>::type
Chris@16 996 as_expr(T const &t)
Chris@16 997 {
Chris@16 998 return typename Domain::template as_expr<T const>()(t);
Chris@16 999 }
Chris@16 1000
Chris@16 1001 /// \brief A function that wraps non-Proto expression types in Proto
Chris@16 1002 /// terminals (by reference) and returns Proto expression types by
Chris@16 1003 /// reference
Chris@16 1004 ///
Chris@16 1005 /// The <tt>as_child()</tt> function turns objects into Proto terminals if
Chris@16 1006 /// they are not Proto expression types already. Non-Proto types are
Chris@16 1007 /// held by reference. Types which are already Proto types are simply
Chris@16 1008 /// returned as-is.
Chris@16 1009 ///
Chris@16 1010 /// This function can be called either with an explicitly specified
Chris@16 1011 /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or
Chris@16 1012 /// without (i.e., <tt>as_child(t)</tt>). If no domain is
Chris@16 1013 /// specified, \c default_domain is assumed.
Chris@16 1014 ///
Chris@16 1015 /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
Chris@16 1016 /// returned as-is. Otherwise, \c as_child() returns
Chris@16 1017 /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>.
Chris@16 1018 ///
Chris@16 1019 /// \param t The object to wrap.
Chris@16 1020 template<typename T>
Chris@16 1021 BOOST_FORCEINLINE
Chris@16 1022 typename add_const<typename result_of::as_child<T, default_domain>::type>::type
Chris@16 1023 as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
Chris@16 1024 {
Chris@16 1025 return default_domain::as_child<T>()(t);
Chris@16 1026 }
Chris@16 1027
Chris@16 1028 /// \overload
Chris@16 1029 ///
Chris@16 1030 template<typename T>
Chris@16 1031 BOOST_FORCEINLINE
Chris@16 1032 typename add_const<typename result_of::as_child<T const, default_domain>::type>::type
Chris@16 1033 as_child(T const &t)
Chris@16 1034 {
Chris@16 1035 return default_domain::as_child<T const>()(t);
Chris@16 1036 }
Chris@16 1037
Chris@16 1038 /// \overload
Chris@16 1039 ///
Chris@16 1040 template<typename Domain, typename T>
Chris@16 1041 BOOST_FORCEINLINE
Chris@16 1042 typename add_const<typename result_of::as_child<T, Domain>::type>::type
Chris@16 1043 as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
Chris@16 1044 {
Chris@16 1045 return typename Domain::template as_child<T>()(t);
Chris@16 1046 }
Chris@16 1047
Chris@16 1048 /// \overload
Chris@16 1049 ///
Chris@16 1050 template<typename Domain, typename T>
Chris@16 1051 BOOST_FORCEINLINE
Chris@16 1052 typename add_const<typename result_of::as_child<T const, Domain>::type>::type
Chris@16 1053 as_child(T const &t)
Chris@16 1054 {
Chris@16 1055 return typename Domain::template as_child<T const>()(t);
Chris@16 1056 }
Chris@16 1057
Chris@16 1058 /// \brief Return the Nth child of the specified Proto expression.
Chris@16 1059 ///
Chris@16 1060 /// Return the Nth child of the specified Proto expression. If
Chris@16 1061 /// \c N is not specified, as in \c child(expr), then \c N is assumed
Chris@16 1062 /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
Chris@16 1063 /// reference.
Chris@16 1064 ///
Chris@16 1065 /// \param expr The Proto expression.
Chris@16 1066 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
Chris@16 1067 /// \pre \c N is an MPL Integral Constant.
Chris@16 1068 /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
Chris@16 1069 /// \throw nothrow
Chris@16 1070 /// \return A reference to the Nth child
Chris@16 1071 template<typename N, typename Expr>
Chris@16 1072 BOOST_FORCEINLINE
Chris@16 1073 typename result_of::child<Expr &, N>::type
Chris@16 1074 child(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
Chris@16 1075 {
Chris@16 1076 return result_of::child<Expr &, N>::call(e);
Chris@16 1077 }
Chris@16 1078
Chris@16 1079 /// \overload
Chris@16 1080 ///
Chris@16 1081 template<typename N, typename Expr>
Chris@16 1082 BOOST_FORCEINLINE
Chris@16 1083 typename result_of::child<Expr const &, N>::type
Chris@16 1084 child(Expr const &e)
Chris@16 1085 {
Chris@16 1086 return result_of::child<Expr const &, N>::call(e);
Chris@16 1087 }
Chris@16 1088
Chris@16 1089 /// \overload
Chris@16 1090 ///
Chris@16 1091 template<typename Expr2>
Chris@16 1092 BOOST_FORCEINLINE
Chris@16 1093 typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::reference
Chris@16 1094 child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
Chris@16 1095 {
Chris@16 1096 return expr2.proto_base().child0;
Chris@16 1097 }
Chris@16 1098
Chris@16 1099 /// \overload
Chris@16 1100 ///
Chris@16 1101 template<typename Expr2>
Chris@16 1102 BOOST_FORCEINLINE
Chris@16 1103 typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::const_reference
Chris@16 1104 child(Expr2 const &expr2)
Chris@16 1105 {
Chris@16 1106 return expr2.proto_base().child0;
Chris@16 1107 }
Chris@16 1108
Chris@16 1109 /// \brief Return the Nth child of the specified Proto expression.
Chris@16 1110 ///
Chris@16 1111 /// Return the Nth child of the specified Proto expression. The child
Chris@16 1112 /// is returned by reference.
Chris@16 1113 ///
Chris@16 1114 /// \param expr The Proto expression.
Chris@16 1115 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
Chris@16 1116 /// \pre <tt>N \< Expr::proto_arity::value</tt>
Chris@16 1117 /// \throw nothrow
Chris@16 1118 /// \return A reference to the Nth child
Chris@16 1119 template<long N, typename Expr>
Chris@16 1120 BOOST_FORCEINLINE
Chris@16 1121 typename result_of::child_c<Expr &, N>::type
Chris@16 1122 child_c(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
Chris@16 1123 {
Chris@16 1124 return result_of::child_c<Expr &, N>::call(e);
Chris@16 1125 }
Chris@16 1126
Chris@16 1127 /// \overload
Chris@16 1128 ///
Chris@16 1129 template<long N, typename Expr>
Chris@16 1130 BOOST_FORCEINLINE
Chris@16 1131 typename result_of::child_c<Expr const &, N>::type
Chris@16 1132 child_c(Expr const &e)
Chris@16 1133 {
Chris@16 1134 return result_of::child_c<Expr const &, N>::call(e);
Chris@16 1135 }
Chris@16 1136
Chris@16 1137 /// \brief Return the value stored within the specified Proto
Chris@16 1138 /// terminal expression.
Chris@16 1139 ///
Chris@16 1140 /// Return the value stored within the specified Proto
Chris@16 1141 /// terminal expression. The value is returned by
Chris@16 1142 /// reference.
Chris@16 1143 ///
Chris@16 1144 /// \param expr The Proto terminal expression.
Chris@16 1145 /// \pre <tt>N::value == 0</tt>
Chris@16 1146 /// \throw nothrow
Chris@16 1147 /// \return A reference to the terminal's value
Chris@16 1148 template<typename Expr>
Chris@16 1149 BOOST_FORCEINLINE
Chris@16 1150 typename result_of::value<Expr &>::type
Chris@16 1151 value(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
Chris@16 1152 {
Chris@16 1153 return e.proto_base().child0;
Chris@16 1154 }
Chris@16 1155
Chris@16 1156 /// \overload
Chris@16 1157 ///
Chris@16 1158 template<typename Expr>
Chris@16 1159 BOOST_FORCEINLINE
Chris@16 1160 typename result_of::value<Expr const &>::type
Chris@16 1161 value(Expr const &e)
Chris@16 1162 {
Chris@16 1163 return e.proto_base().child0;
Chris@16 1164 }
Chris@16 1165
Chris@16 1166 /// \brief Return the left child of the specified binary Proto
Chris@16 1167 /// expression.
Chris@16 1168 ///
Chris@16 1169 /// Return the left child of the specified binary Proto expression. The
Chris@16 1170 /// child is returned by reference.
Chris@16 1171 ///
Chris@16 1172 /// \param expr The Proto expression.
Chris@16 1173 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
Chris@16 1174 /// \pre <tt>2 == Expr::proto_arity::value</tt>
Chris@16 1175 /// \throw nothrow
Chris@16 1176 /// \return A reference to the left child
Chris@16 1177 template<typename Expr>
Chris@16 1178 BOOST_FORCEINLINE
Chris@16 1179 typename result_of::left<Expr &>::type
Chris@16 1180 left(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
Chris@16 1181 {
Chris@16 1182 return e.proto_base().child0;
Chris@16 1183 }
Chris@16 1184
Chris@16 1185 /// \overload
Chris@16 1186 ///
Chris@16 1187 template<typename Expr>
Chris@16 1188 BOOST_FORCEINLINE
Chris@16 1189 typename result_of::left<Expr const &>::type
Chris@16 1190 left(Expr const &e)
Chris@16 1191 {
Chris@16 1192 return e.proto_base().child0;
Chris@16 1193 }
Chris@16 1194
Chris@16 1195 /// \brief Return the right child of the specified binary Proto
Chris@16 1196 /// expression.
Chris@16 1197 ///
Chris@16 1198 /// Return the right child of the specified binary Proto expression. The
Chris@16 1199 /// child is returned by reference.
Chris@16 1200 ///
Chris@16 1201 /// \param expr The Proto expression.
Chris@16 1202 /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
Chris@16 1203 /// \pre <tt>2 == Expr::proto_arity::value</tt>
Chris@16 1204 /// \throw nothrow
Chris@16 1205 /// \return A reference to the right child
Chris@16 1206 template<typename Expr>
Chris@16 1207 BOOST_FORCEINLINE
Chris@16 1208 typename result_of::right<Expr &>::type
Chris@16 1209 right(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
Chris@16 1210 {
Chris@16 1211 return e.proto_base().child1;
Chris@16 1212 }
Chris@16 1213
Chris@16 1214 /// \overload
Chris@16 1215 ///
Chris@16 1216 template<typename Expr>
Chris@16 1217 BOOST_FORCEINLINE
Chris@16 1218 typename result_of::right<Expr const &>::type
Chris@16 1219 right(Expr const &e)
Chris@16 1220 {
Chris@16 1221 return e.proto_base().child1;
Chris@16 1222 }
Chris@16 1223
Chris@16 1224 /// INTERNAL ONLY
Chris@16 1225 ///
Chris@16 1226 template<typename Domain>
Chris@16 1227 struct is_callable<functional::as_expr<Domain> >
Chris@16 1228 : mpl::true_
Chris@16 1229 {};
Chris@16 1230
Chris@16 1231 /// INTERNAL ONLY
Chris@16 1232 ///
Chris@16 1233 template<typename Domain>
Chris@16 1234 struct is_callable<functional::as_child<Domain> >
Chris@16 1235 : mpl::true_
Chris@16 1236 {};
Chris@16 1237
Chris@16 1238 /// INTERNAL ONLY
Chris@16 1239 ///
Chris@16 1240 template<long N>
Chris@16 1241 struct is_callable<functional::child_c<N> >
Chris@16 1242 : mpl::true_
Chris@16 1243 {};
Chris@16 1244
Chris@16 1245 /// INTERNAL ONLY
Chris@16 1246 ///
Chris@16 1247 template<typename N>
Chris@16 1248 struct is_callable<functional::child<N> >
Chris@16 1249 : mpl::true_
Chris@16 1250 {};
Chris@16 1251
Chris@16 1252 }}
Chris@16 1253
Chris@101 1254 #if defined(_MSC_VER)
Chris@16 1255 # pragma warning(pop)
Chris@16 1256 #endif
Chris@16 1257
Chris@16 1258 #endif