1[/ 2 / Copyright (c) 2015 Boost.Test contributors 3 / 4 / Distributed under the Boost Software License, Version 1.0. (See accompanying 5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 /] 7 8 9[section:internal_details `BOOST_TEST`: details on expressions] 10Let's consider the following example: 11 12[bt_example boost_test_macro3..BOOST_TEST reporting..run-fail] 13 14It was already mentioned that the reporting is not symmetrical (see [link boost_test.testing_tools.reports here]). 15An expression is constructed from the `statement` appearing in the `BOOST_TEST` macro. This expression allows evaluation and reporting such 16as `"13 - 1 >= 12" failed` along with a copy of the `statement`, which contains more details than `"a - 1 < b" failed`. 17In details, what happens is the following: 18 19# a special object, the `seed` of the expression, is composed from the left side of `statement`. 20 This initial composition has highest precedence over the supported operations. The expression below: 21 22 a op1 b op2 c op3 d 23 24 is actually seen as 25 26 ( seed a ) op1 b op2 c op3 d 27 28# The "`seed a`" returns an `expression` object that keep tracks of the type of `a`. This expression 29 has overloads for left-to-right associativity, and the 30 operations `op1`, `op2` ... are /chained/ to the right of this expression object: 31 32 a op1 b 33 34 yields to the pseudo-code 35 36 expression1 = create-expression(a) 37 expression2 = create-expression(expression1, op1, b) 38 39 `expression1` and `expression2` keep track of their left and right operands, and the operation on those operands. The 40 expressions keep also track of the result type of the associated sub-expression. In the above example, `expression1` and `expression2` 41 have result type `decltype(a)` and `decltype(a op1 b)` respectively. The result type allows for chaining 42 sub-expressions. 43 44# The C++ operators precedence rules apply in any case. What is seen by the expression is what is reachable with left-to-right 45 composition. Any other operation that happens before it reaches the expression's right operand is not parsed as a sub-expression 46 and is seen as a single operand: the right operand is not developed further by the framework. 47 Let's suppose `op2` below has higher precedence than `op1`, then 48 49 a op1 b op2 c 50 51 is equivalent to: 52 53 create-expression(create-expression(a), op1, (b op2 c)) 54 55 In the above statement, the final expression can only see the result of `(b op2 c)` to its right, for which no further detail 56 can be provided in the logs. This is also the case for /right-to-left/ associative operators, such as `!`, `~`, `-` (unary negation) 57 etc. 58 59 [caution Since the `expression` object is composed from left-to-right, it actually observes a chain of operations and 60 not the full expression tree.] 61 62# Once the full expression chain is built, it is evaluated as a chain of sub-expressions from left-to-right, exactly as the 63 composition rule above. The evaluated elements are the ones of the expression itself. The expression 64 65 a op1 b 66 67 yields to the following evaluation chain: 68 69 expression2.result = expression1.result op1 b 70 expression1.result = a 71 72 The final expression of the statement is cast to a boolean, which is in turn evaluated by the __UTF__. 73 74 75The example below illustrates the construction of the left-to-right /chained/ expression. 76 77[bt_example boost_test_macro2..BOOST_TEST compound statements..run-fail] 78[endsect] 79