123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- [/==============================================================================
- Copyright (C) 2001-2010 Joel de Guzman
- Copyright (C) 2001-2005 Dan Marsden
- Copyright (C) 2001-2010 Thomas Heller
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ===============================================================================/]
- [section Operator]
- #include <boost/phoenix/operator.hpp>
- This facility provides a mechanism for lazily evaluating operators.
- Syntactically, a lazy operator looks and feels like an ordinary C/C++ infix,
- prefix or postfix operator. The operator application looks the same. However,
- unlike ordinary operators, the actual operator execution is deferred. Samples:
- arg1 + arg2
- 1 + arg1 * arg2
- 1 / -arg1
- arg1 < 150
- We have seen the lazy operators in action (see [link phoenix.starter_kit.lazy_operators
- Quick Start - Lazy Operators]). Let's go back and examine them a little bit further:
- std::find_if(c.begin(), c.end(), arg1 % 2 == 1)
- Through operator overloading, the expression `arg1 % 2 == 1` actually generates
- an actor. This actor object is passed on to STL's `find_if` function. From
- the viewpoint of STL, the expression is simply a function object expecting a
- single argument of the containers value_type. For each element in `c`,
- the element is passed on as an argument `arg1` to the actor (function
- object). The actor checks if this is an odd value based on the expression
- `arg1 % 2 == 1` where arg1 is replaced by the container's element.
- Like lazy functions (see
- [link phoenix.modules.function Function]), lazy operators are not immediately executed
- when invoked. Instead, an actor (see [link phoenix.actor Actor])
- object is created and returned to the caller. Example:
- (arg1 + arg2) * arg3
- does nothing more than return an actor. A second function call will evaluate
- the actual operators. Example:
- std::cout << ((arg1 + arg2) * arg3)(4, 5, 6);
- will print out "54".
- Operator expressions are lazily evaluated following four simple rules:
- # A binary operator, except `->*` will be lazily evaluated when
- /at least/ one of its operands is an actor object
- (see [link phoenix.actor Actor]).
- # Unary operators are lazily evaluated if their argument is an actor object.
- # Operator `->*` is lazily evaluated if the left hand argument is an actor object.
- # The result of a lazy operator is an actor object that can in turn allow the
- applications of rules 1, 2 and 3.
- For example, to check the following expression is lazily evaluated:
- -(arg1 + 3 + 6)
- # Following rule 1, `arg1 + 3` is lazily evaluated since `arg1` is an actor
- (see [link phoenix.modules.core.arguments Arguments]).
- # The result of this `arg1 + 3` expression is an actor object, following rule 4.
- # Continuing, `arg1 + 3 + 6` is again lazily evaluated.
- Rule 2.
- # By rule 4 again, the result of `arg1 + 3 + 6` is an actor object.
- # As `arg1 + 3 + 6` is an actor, `-(arg1 + 3 + 6)` is lazily evaluated. Rule 2.
- Lazy-operator application is highly contagious. In most cases, a single `argN`
- actor infects all its immediate neighbors within a group (first level or
- parenthesized expression).
- Note that at least one operand of any operator must be a valid actor
- for lazy evaluation to take effect. To force lazy evaluation of an
- ordinary expression, we can use `ref(x)`, `val(x)` or `cref(x)` to
- transform an operand into a valid actor object (see [link phoenix.modules.core Core]).
- For example:
- 1 << 3; // Immediately evaluated
- val(1) << 3; // Lazily evaluated
- [heading Supported operators]
- [heading Unary operators]
- prefix: ~, !, -, +, ++, --, & (reference), * (dereference)
- postfix: ++, --
- [heading Binary operators]
- =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
- +, -, *, /, %, &, |, ^, <<, >>
- ==, !=, <, >, <=, >=
- &&, ||, ->*
- [heading Ternary operator]
- if_else(c, a, b)
- The ternary operator deserves special mention. Since C++ does not allow us to
- overload the conditional expression: `c ? a : b`, the if_else pseudo function is
- provided for this purpose. The behavior is identical, albeit in a lazy manner.
- [heading Member pointer operator]
- a->*member_object_pointer
- a->*member_function_pointer
- The left hand side of the member pointer operator must be an actor returning a pointer
- type. The right hand side of the member pointer operator may be either a pointer to member
- object or pointer to member function.
- If the right hand side is a member object pointer, the result is an actor which, when evaluated,
- returns a reference to that member. For example:
- struct A
- {
- int member;
- };
- A* a = new A;
- ...
- (arg1->*&A::member)(a); // returns member a->member
- If the right hand side is a member function pointer, the result is an actor which, when invoked, calls the specified member function. For example:
- struct A
- {
- int func(int);
- };
- A* a = new A;
- int i = 0;
- (arg1->*&A::func)(arg2)(a, i); // returns a->func(i)
- [heading Include Files]
- [table
- [[Operators] [File]]
- [[`-`, `+`, `++`, `--`, `+=`,
- `-=`, `*=`, `/=`, `%=`,
- `*`, `/`, `%`] [`#include <boost/phoenix/operator/arithmetic.hpp>`]]
- [[`&=`, `|=`, `^=`, `<<=`,
- `>>=`, `&`, `|`, `^`, `<<`,
- `>>`] [`#include <boost/phoenix/operator/bitwise.hpp>`]]
- [[`==`, `!=`, `<`,
- `<=`, `>`, `>=`] [`#include <boost/phoenix/operator/comparison.hpp>`]]
- [[`<<`, `>>`] [`#include <boost/phoenix/operator/io.hpp>`]]
- [[`!`, &&, `||`] [`#include <boost/phoenix/operator/logical.hpp>`]]
- [[`&x`, `*p`, `=`, `[]`] [`#include <boost/phoenix/operator/self.hpp>`]]
- [[`if_else(c, a, b)`] [`#include <boost/phoenix/operator/if_else.hpp>`]]
- [[`->*`] [`#include <boost/phoenix/operator/member.hpp>`]]
- ]
- [endsect]
|