Update doc

This commit is contained in:
Patrick Pelissier committed 2024-06-15 09:45:13 +02:00
1 parent 3f102c2270
commit 47a51ee5c4
1 file changed
+38 -17
+38 -17
View File
@@ -6889,27 +6889,33 @@ for M_EACH(item, list, LIST_OPLIST) { action; }
##### `M_LET(var1[,var2[,...]], oplist|type)` ##### `M_LET(var1[,var2[,...]], oplist|type)`
This macro defines the variable `var1`(resp. `var2`, `...`) of oplist `oplist`. This macro defines the variable `var1`(resp. `var2`, `...`) with the oplist `oplist` for the next block of code.
If a type (instead of an oplist) is used, the oplist of the type shall have been registered globally. A type can be used instead of an oplist, in which case the macro will use the oplist globally associated to this type.
It initializes `var1` (resp. `var2`, `...`) by calling the initialization method, Then the oplist is used to get the constructor methods and destructor method of the type.
It initializes `var1` (resp. `var2`, `...`) by calling the right initialization method
in function of the given context
and clears `var1` (resp. `var2`, `...`) by calling the clear method and clears `var1` (resp. `var2`, `...`) by calling the clear method
when the bracket associated to the `M_LET` go out of scope. when the bracket associated to the `M_LET` go out of scope.
If the exception model is activated, the clear method is also called if an exception is thrown in the next block of code.
The ̀`M_LET` macro enables support of [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)
Its formulation is based on the expression `let var1 as type in` Its formulation is based on the expression `let var1 as type in`
Several forms are supported for the initialization method: Several forms are supported for the context of the initialization method:
* If `var1` (resp. `var2`, `...`) has the form (`v1`, `arguments...`), * If `var1` (resp. `var2`, `...`) has the form (`v1`, `arguments...`),
then the variable `v1` will be initialized with the then the variable `v1` will be initialized with the
contains of the initializing list `arguments...`. contains of the initializing list `arguments...`.
* If `arguments` is single and within parenthesis * If `arguments...` is a single argument within parenthesis
or if there is more one argument or if there is more one argument
or if the property `LET_AS_INIT_WITH` of the type is defined, or if the property `LET_AS_INIT_WITH` of the oplist is defined,
it will use the operator `INIT_WITH` (if it exists) to emplace the variable then it uses the operator `INIT_WITH` (if it exists) to emplace the variable
with the given arguments. The arguments are therefore expected to be compatible with with the given arguments (The arguments are therefore expected to be compatible with
the `INIT_WITH` operator. the `INIT_WITH` operator).
* Otherwise, it will use the operator `INIT_SET` (argument is expected * Otherwise, it will use the operator `INIT_SET` (argument is expected
to be the same type as the initialized type in such case). to be the same type as the initialized type in such case) if there is a single argument.
* Otherwise, it will use the empty initializer `INIT` operator. * Otherwise, it will use the empty initializer `INIT` operator.
> [!IMPORTANT] > [!IMPORTANT]
@@ -6920,24 +6926,39 @@ to be the same type as the initialized type in such case).
> with the `INIT_WITH` detection it is needed to put something outside the > with the `INIT_WITH` detection it is needed to put something outside the
> parenthesis like a cast). > parenthesis like a cast).
An argument shall not have any post effect when it is evaluated. An argument shall not have any post effect when it is evaluated as the macro may evaulate it multiple times.
There shall be at most one `M_LET` macro per line of source code. There shall be at most one `M_LET` macro per line of source code.
Example: You shall not call the destructor operator with the next block of code.
Examples:
```C
M_LET(a, STRING_OPLIST) { string_set_str(a, "Hello world"); string_fputs(stdout, a); }
// a no longer exists
```
```C ```C
M_LET(a, STRING_OPLIST) { do something with a } or
M_LET(a, b, c, string_t) { do something with a, b & c } M_LET(a, b, c, string_t) { do something with a, b & c }
M_LET( (a, ("Hello")), string_t) { do something with a initialized to "Hello" } // a, b, c no longer exists
```
```C
M_LET( (a, ("Hello")), string_t) { string_fputs(stdout, a); }
```
```C
M_LET( (a, ("Hello")), string_t)
M_LET( (b, a), string_t){ string_fputs(stdout, b); }
``` ```
> [!NOTE] > [!NOTE]
> The user code shall not perform a return or a goto (or `longjmp`) > The user code shall not perform a return or a goto (or `longjmp`) within the next block
> Outside the `{}` or a call to an exit function > with a terget outside this block or a call to an exit function.
> Otherwise the clear code of the object won't be called. > Otherwise the clear code of the object won't be called.
> However, you can use the break instruction to quit the block > However, you can use the break instruction to quit the block
> (the clear function will be executed). > (the clear function will be executed) or throw an exception.
You can chain the `M_LET` macro to create several different variables. You can chain the `M_LET` macro to create several different variables.