mirror of
https://github.com/boostorg/yap.git
synced 2026-02-22 16:02:10 +00:00
109 lines
4.2 KiB
Plaintext
109 lines
4.2 KiB
Plaintext
[section Tutorial]
|
|
|
|
[import ../example/minimal.cpp]
|
|
[import ../example/lazy_vector.cpp]
|
|
|
|
[heading Expressions]
|
|
|
|
_yap_ consists of expressions and functions that operate on them. Any type
|
|
that models the _Expr_ concept will work with any of the functions in _yap_
|
|
that takes an expression.
|
|
|
|
For a type `T` to model the _Expr_ concept, `T` must contain at least an
|
|
_kind_ (terminal, plus-operation, etc.) and a _tuple_ of values. That's it.
|
|
This means that user-defined templates modelling _ExprTmpl_ are very
|
|
straightforward to make.
|
|
|
|
[note The _tuple_ of values is also constrained, based on the kind of the
|
|
expression; see the full _Expr_ documentation for details.]
|
|
|
|
Here's an example:
|
|
|
|
[minimal_template]
|
|
|
|
That's a template that models _ExprTmpl_. Instantiated with the proper
|
|
template parameters, it produces _Exprs_.
|
|
|
|
Ok, so it's not that interesting by itself -- it has no operators. But we can
|
|
still use it with the _yap_ functions that take an _Expr_. Let's make a
|
|
plus-expression manually:
|
|
|
|
[minimal_template_manual_construction]
|
|
|
|
And if we evaluate it using _eval_, it does what you would expect:
|
|
|
|
[minimal_template_evaluation]
|
|
|
|
There is a reference model of the _ExprTmpl_ concept that comes with _yap_:
|
|
_expr_. It has all the member operators defined, and the nonmember operators
|
|
and the `if_else` pseudo-operator are defined in their repsective headers.
|
|
|
|
_expr_ is great for prototyping, and for quick-and-dirty uses of _et_, but its
|
|
use of every single operator makes it a suboptimal choice for most use cass.
|
|
|
|
[heading Kinds of Expressions]
|
|
|
|
There are four special kinds of expression.
|
|
|
|
[variablelist Special Expression Kinds
|
|
[[_terminal_] [A terminal contains a non-Expression value, and represents the leaf-node in an
|
|
expression tree.]]
|
|
[[_placeholder_] [A placeholder is a stand-in for some value to be provided later.]]
|
|
[[_if_else_] [An `if_else` expression is analogous to the C++ ternary operator (`?:`), but
|
|
without the common-type conversion logic.]]
|
|
[[_expr_ref_] [An `exp_ref` expression is one that acts as a (possibly `const`) lvalue reference to another expression. It exists to prevent unnecessary copies of expressions.]]
|
|
]
|
|
|
|
The other expression kinds are all the overloadable operators, See _kind_ for
|
|
the full list.
|
|
|
|
[heading Operators]
|
|
|
|
Let's see an expression template type with some operators:
|
|
|
|
[lazy_vector_decl]
|
|
|
|
Those macros are used to define operator overloads that return _Exprs_. As
|
|
shown here, that sort of operator can be mixed with normal, non-lazy ones.
|
|
|
|
Use of the macros is not necessary (you can write your own operators that
|
|
return _Exprs_ if you like), but it is suitable 99% of the time.
|
|
|
|
Making the operators easy to define like this allows you to define custom
|
|
expression templates that have only the operators defined that are appropriate
|
|
for your use case.
|
|
|
|
[heading Operator Macros]
|
|
|
|
There are macros that define binary operators as members and as nonmembers.
|
|
For a given operator the member-defining macro will define an operator that
|
|
accepts anything on the right (making a terminal out of a non-_Expr_ operand);
|
|
the nonmember-defining macro will define an operator that will only accept a
|
|
non-_Expr_ on the left and an _Expr_ on the right. This is to avoid creating
|
|
ambiguous overload sets. Here are the macros and their uses:
|
|
|
|
[table Unary and Binary Operator-Defining Macros
|
|
[[Macro] [First/Left Operand] [Right Operand]]
|
|
|
|
[[_unary_member_m_] [Any type.] []]
|
|
[[_binary_member_m_] [Any type.] [Any type.]]
|
|
[[_binary_free_m_] [Any non-_Expr_.] [_Expr_]]
|
|
[[_udt_unary_m_] [Any non-_Expr_ that satisfies the given type trait.] []]
|
|
[[_udt_udt_unary_m_] [Any non-_Expr_ that satisfies the given (left-hand) type trait.] [Any non-_Expr_ that satisfies the given (right-hand) type trait.]]
|
|
[[_udt_any_unary_m_] [Any non-_Expr_.] [At least one parameter must satisfy the given type trait.]]
|
|
]
|
|
|
|
[table The Other Operator-Defining Macros
|
|
[[Macro] [Operands] [Notes]]
|
|
|
|
[[_member_call_m_] [Any type.] []]
|
|
[[_expr_if_else_m_] [Any type.] [At least one parameter must be an _Expr_.]]
|
|
[[_udt_any_if_else_m_] [Any non-_Expr_.] [At least one parameter must satisfy the given type trait.]]
|
|
]
|
|
|
|
[heading How Expression Operands Are Treated]
|
|
|
|
TODO
|
|
|
|
[endsect]
|