Compare commits
78
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a96845fac | ||
|
|
b742881ebc | ||
|
|
f7f5db61d3 | ||
|
|
32b00eb433 | ||
|
|
796f2619e5 | ||
|
|
268192138a | ||
|
|
0671a2ea41 | ||
|
|
07dce84e51 | ||
|
|
5f4303624f | ||
|
|
19e61467d5 | ||
|
|
1454bcebe4 | ||
|
|
d48f2ff84d | ||
|
|
269636b4d8 | ||
|
|
bf68340106 | ||
|
|
5dba526e29 | ||
|
|
469239adcd | ||
|
|
589abda0c2 | ||
|
|
8f141896ba | ||
|
|
a0cbec4329 | ||
|
|
df66db562d | ||
|
|
1829a70601 | ||
|
|
e9b25f2414 | ||
|
|
c9bb739f24 | ||
|
|
e049b83a9e | ||
|
|
31ac3999a1 | ||
|
|
a0818419ab | ||
|
|
496f885a84 | ||
|
|
d5d9a4bd5c | ||
|
|
ca9571a110 | ||
|
|
4497214b9c | ||
|
|
ccb1658afd | ||
|
|
eaf2783f1a | ||
|
|
5705819814 | ||
|
|
91f5f513c4 | ||
|
|
3dec4e2cbe | ||
|
|
e70766beaa | ||
|
|
d7639f0ae0 | ||
|
|
c63ce84e45 | ||
|
|
a043c379c0 | ||
|
|
92bb380117 | ||
|
|
6bb7a184db | ||
|
|
fa9163be9d | ||
|
|
0bade1563c | ||
|
|
1278d2f8a0 | ||
|
|
53af2aae68 | ||
|
|
17ded6fcc8 | ||
|
|
19ce371533 | ||
|
|
0bd1bcb68e | ||
|
|
b50813713a | ||
|
|
2628536d20 | ||
|
|
ecfa4a9152 | ||
|
|
dafe4bcec5 | ||
|
|
8544a7f289 | ||
|
|
aa18915d61 | ||
|
|
df4bc0a56c | ||
|
|
b6046e5e23 | ||
|
|
b487bfe5ad | ||
|
|
408272c810 | ||
|
|
6a9ee17eca | ||
|
|
05c5a94634 | ||
|
|
b1b0927e9f | ||
|
|
37770365a1 | ||
|
|
82bdcc685a | ||
|
|
26fa733f70 | ||
|
|
cd2fc05573 | ||
|
|
33430d4359 | ||
|
|
dc95b49f05 | ||
|
|
3ec24cfa40 | ||
|
|
12b099dcf8 | ||
|
|
b885d6136c | ||
|
|
b51c4bea2b | ||
|
|
302c5eb300 | ||
|
|
6d2900a2bd | ||
|
|
573e09c56e | ||
|
|
0a39a17d36 | ||
|
|
a913d0947c | ||
|
|
abbd8ad6ce | ||
|
|
a09c9fe1c3 |
No files matched your search
@@ -38,6 +38,7 @@ depend
|
||||
other/
|
||||
a*.dat
|
||||
config
|
||||
config.link
|
||||
*.log
|
||||
.vscode
|
||||
.vs
|
||||
|
||||
@@ -26,9 +26,9 @@ M\*LIB: Generic type-safe Container Library for C language
|
||||
12. [Fixed buffer queue](#m-buffer)
|
||||
13. [Atomic Shared Register](#m-snapshot)
|
||||
14. [Shared pointers](#m-shared)
|
||||
15. [Intrusie Shared Pointers](#m-i-shared)
|
||||
15. [Intrusive Shared Pointers](#m-i-shared)
|
||||
16. [Intrusive list](#m-i-list)
|
||||
17. [Concurrent adaptator](#m-concurrent)
|
||||
17. [Concurrent adapter](#m-concurrent)
|
||||
18. [Bitset](#m-bitset)
|
||||
19. [String](#m-string)
|
||||
20. [Core preprocessing](#m-core)
|
||||
@@ -42,28 +42,29 @@ M\*LIB: Generic type-safe Container Library for C language
|
||||
28. [JSON Serialization](#m-serial-json)
|
||||
29. [Binary Serialization](#m-serial-bin)
|
||||
12. [Global User Customization](#global-user-customization)
|
||||
13. [Licence](#license)
|
||||
|
||||
13. [License](#license)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
M\*LIB (M star lib) is a C library enabling to define and use **generic and
|
||||
type safe container**, aka handling generic
|
||||
M\*LIB (M star lib) is a C library enabling to define and to use **generic and
|
||||
type safe container** in C, aka handling generic
|
||||
[containers](https://en.wikipedia.org/wiki/Container_%28abstract_data_type%29) in in pure C language.
|
||||
The objects within the containers can be trivial or very complex:
|
||||
they can have their own constructor, destructor, operators
|
||||
or can be basic C type like the C type 'int'.
|
||||
The encapsulated objects can have their own constructor, destructor, operators
|
||||
or can be basic C type like the C type 'int': both are fully supported.
|
||||
This makes it possible to construct fully
|
||||
recursive objects (container-of[...]-container-of-type-T),
|
||||
without erasing type information (typically using void pointers or resorting
|
||||
to C macro to access the container).
|
||||
recursive container objects (container-of[...]-container-of-type-T)
|
||||
while keeping compile time type checking.
|
||||
|
||||
This is an equivalent of the [C++](https://en.wikipedia.org/wiki/C%2B%2B)
|
||||
[Standard Library](https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library)
|
||||
but for standard ISO C99 / C11.
|
||||
[Standard Library](https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library),
|
||||
providing vector, deque, forward_list, set, map, multiset, multimap,
|
||||
unordered_set, unordered_map, stack, queue, shared_ptr, string, variant, option
|
||||
to standard ISO C99 / C11.
|
||||
There is not a strict mapping as both the STL and M\*LIB have their exclusive containers:
|
||||
See [here](https://github.com/P-p-H-d/mlib/wiki/STL-to-M*LIB-mapping) for details.
|
||||
M\*LIB provides also additional concurrent containers to design properly
|
||||
multi-threaded programs: shared register, communication queue, ...
|
||||
|
||||
M\*LIB is portable to any systems that support [ISO C99](https://en.wikipedia.org/wiki/C99).
|
||||
Some optional features need at least [ISO C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)).
|
||||
@@ -78,7 +79,7 @@ One of M\*LIB design key is to ensure safety. This is done by multiple means:
|
||||
|
||||
* in debug mode, defensive programming is extensively used:
|
||||
the contracts of the function are checked, ensuring
|
||||
that the data are not corrupted. For example,
|
||||
that the data are not corrupted. For example, strict
|
||||
[Buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) are checked in this mode
|
||||
through [bound checking](https://en.wikipedia.org/wiki/Bounds_checking)
|
||||
or the intrinsic properties of a Red-Black tree (for example) are verified.
|
||||
@@ -86,12 +87,12 @@ One of M\*LIB design key is to ensure safety. This is done by multiple means:
|
||||
* as few cast as possible are used within the library (casts are the evil of safety).
|
||||
Still the library can be used with the greatest level of warnings by a C compiler without
|
||||
any aliasing warning.
|
||||
* the genericity is not done directly by macro, but indirectly by making them
|
||||
* the genericity is not done directly by macro (which usually prevent type safety), but indirectly by making them
|
||||
define inline functions with the proper prototypes: this enables
|
||||
the user calls to have proper warning checks.
|
||||
* extensive testing: the library is tested on the main targets using Continuous Integration with a coverage of the test suite of nearly 99%.
|
||||
the user calls to have proper error and warning checks.
|
||||
* extensive testing: the library is tested on the main targets using Continuous Integration with a coverage of the test suite of more than 99%.
|
||||
The test suite itself is run through the multiple sanitizers defined by GCC/CLANG (Address, undefined, leak, thread).
|
||||
The test suite also includes a comparison of equivalent behaviors of M\*LIB with the C++ STL using random genetic algorithms.
|
||||
The test suite also includes a comparison of equivalent behaviors of M\*LIB with the C++ STL using random testing or fuzzer testing.
|
||||
* static analysis: multiple static analyzer (like scan-build or GCC fanalyzer or CodeQL) are run on the generated code, and the results analyzed.
|
||||
|
||||
Other key designs are:
|
||||
@@ -114,12 +115,18 @@ is one of the fastest generic C/C++ library you can find.
|
||||
|
||||
M\*LIB uses internally the 'malloc', 'realloc' and 'free' functions to handle
|
||||
the memory pool. This behavior can be overridden at different level.
|
||||
M\*LIB default policy is to abort the program if there is a memory error.
|
||||
Its default policy is to abort the program if there is a memory error.
|
||||
However, this behavior can also be customized globally.
|
||||
M\*LIB supports also the exception error model by providing its own implementation of the try / catch mechanism.
|
||||
This mechanism is compatible with [RAII programming](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization):
|
||||
when an exception is thrown, the destructors of the constructed objects are called (See [m-try](#m-try) for more details).
|
||||
|
||||
M\*LIB may use a lot of assertions in its implementation to ensure safety:
|
||||
it is highly recommended to properly define NDEBUG for released programs.
|
||||
|
||||
M\*LIB provides automatically several [serialization](https://en.wikipedia.org/wiki/Serialization) methods for each containers.
|
||||
You can read or write your full and complex data structure into [JSON](https://en.wikipedia.org/wiki/JSON) format in a few lines.
|
||||
|
||||
M\*LIB is distributed under BSD-2 simplified license.
|
||||
|
||||
It is strongly advised not to read the source to know how to use the library
|
||||
@@ -141,8 +148,8 @@ The following headers define containers that don't require the user structure to
|
||||
* [m-list.h](#m-list): header for creating singly-linked list of generic type,
|
||||
* [m-deque.h](#m-deque): header for creating dynamic double-ended queue of generic type,
|
||||
* [m-dict.h](#m-dict): header for creating unordered associative array (through hashmap) or unordered set of generic type,
|
||||
* [m-rbtree.h](#m-rbtree): header for creating ordered set (through binary sorted tree) of generic type,
|
||||
* [m-bptree.h](#m-bptree): header for creating ordered map/set/multimap/multiset (through B+TREE) of generic type,
|
||||
* [m-rbtree.h](#m-rbtree): header for creating ordered set (through Red/Black binary sorted tree) of generic type,
|
||||
* [m-bptree.h](#m-bptree): header for creating ordered map/set/multimap/multiset (through sorted B+TREE) of generic type,
|
||||
* [m-tree.h](#m-tree): header for creating arbitrary tree of generic type,
|
||||
* [m-tuple.h](#m-tuple): header for creating arbitrary tuple of generic types,
|
||||
* [m-variant.h](#m-variant): header for creating arbitrary variant of generic type,
|
||||
@@ -180,7 +187,7 @@ Finally headers for compatibility with non C11 compilers:
|
||||
* [m-atomic.h](#m-atomic): header for ensuring compatibility between C's stdatomic.h and C++'s atomic header (provide also its own implementation if nothing is available),
|
||||
* [m-thread.h](#m-thread): header for providing a very thin layer across multiple implementation of mutex/threads (C11/PTHREAD/WIN32).
|
||||
|
||||
Each containers define their iterators (if it is meaningfull).
|
||||
Each containers define their iterators (if it is meaningful).
|
||||
|
||||
All containers try to expose the same common interface:
|
||||
if the method name is the same, then it does the same thing
|
||||
@@ -604,6 +611,7 @@ Other documented operators are:
|
||||
* NAME() --> prefix: Return the base name (prefix) used to construct the container.
|
||||
* TYPE() --> type: Return the base type associated to this oplist.
|
||||
* SUBTYPE() --> type: Return the type of the element stored in the container (used to iterate over the container).
|
||||
* GENTYPE() --> type: Return the type representing TYPE suitable for a _Generic statement.
|
||||
* OPLIST() --> oplist: Return the oplist of the type of the elements stored in the container.
|
||||
* KEY\_TYPE() --> key\_t: Return the key type for associative containers.
|
||||
* VALUE\_TYPE() --> value\_t: Return the value type for associative containers.
|
||||
@@ -614,7 +622,7 @@ Other documented operators are:
|
||||
* REALLOC(type, type pointer, number) --> type pointer: realloc the given array referenced by type pointer (either a NULL pointer or a pointer returned by the associated REALLOC method itself) to an array of the number of objects of this type and return a pointer to this new array. Previously objects pointed by the pointer are kept up to the minimum of the new size and old one. New objects are not initialized (a constructor operator shall be called afterward). Freed objects are not cleared (A destructor operator shall be called before). The default is M\_MEMORY\_REALLOC (that allocates from the heap). It returns NULL in case of failure in which case the original array is not modified.
|
||||
* FREE (&obj) : free the allocated uninitialized array object 'obj'. The objects are not cleared before being free (CLEAR operator has to be called before). The object shall have been allocated by the associated REALLOC method. The default is M\_MEMORY\_FREE (that frees to the heap).
|
||||
* INC\_ALLOC(size\_t s) -> size\_t: Define the growing policy of an array (or equivalent structure). It returns a new allocation size based on the old allocation size ('s'). Default policy is to get the maximum between '2*s' and 16. NOTE: It doesn't check for overflow: if the returned value is lower than the old one, the user shall raise an overflow error.
|
||||
* INIT\_MOVE(objd, objc): Initialize 'objd' to the same state than 'objc' by stealing as much resources as possible from 'objc', and then clear 'objc' (constructor of objd + destructor of objc). It is semantically equivalent to calling INIT\_SET(objd,objc) then CLEAR(objc) but is usually way faster. Contrary to the C++ choice of using "conservative move" semantic (you still need to call the destructor of a moved object in C++) M\*LIB implements a "destructive move" semantic (this enables better optimization). By default, all objects are assumed to be **trivially movable** (i.e. using memcpy to move an object is safe). Most C objects (even complex structure) are trivially movable and it is a very nice property to have (enabling better optimization). A notable exception are intrusive objects. If an object is not trivially movable, it shall provide an INIT\_MOVE method or disable the INIT\_MOVE method entirely (NOTE: Some containers may assume that the objects are trivially movable). An INIT\_MOVE operator shall not fail. Moved objects shall use the same memory allocator.
|
||||
* INIT\_MOVE(objd, objc): Initialize 'objd' to the same state than 'objc' by stealing as much resources as possible from 'objc', and then clear 'objc' (constructor of objd + destructor of objc). It is semantically equivalent to calling INIT\_SET(objd,objc) then CLEAR(objc) but is usually way faster. Contrary to the C++ choice of using "conservative move" semantic (you still need to call the destructor of a moved object in C++) M\*LIB implements a "destructive move" semantic (this enables better optimization). By default, all objects are assumed to be **trivially movable** (i.e. using memcpy to move an object is safe). Most C objects (even complex structure) are trivially movable and it is a very nice property to have (enabling better optimization). A notable exception are intrusive objects. If an object is not trivially movable, it shall provide an INIT\_MOVE method or disable the INIT\_MOVE method entirely (NOTE: Some containers may assume that the objects are trivially movable). An INIT\_MOVE operator shall not fail (and therefore no exception can be throw). Moved objects shall use the same memory allocator.
|
||||
* MOVE(objd, objc): Set 'objd' to the same state than 'objc' by stealing as resources as possible from 'objc' and then clear 'objc' (destructor of 'objc'). It is equivalent to calling SET(objd,objc) then CLEAR(objc) or CLEAR(objd) and then INIT\_MOVE(objd, objc). See INIT\_MOVE for details and constraints. TBC if this operator is really needed as calling CLEAR then INIT\_MOVE is what do all known implementation, and is efficient.
|
||||
* INIT\_WITH(obj, ...): Initialize the object 'obj' with the given variable set of arguments (constructor). The arguments can be of different types. It is up to the method of the object to decide how to initialize the object based on this initialization array. This operator is used by the M\_LET macro to initialize objects with their given values and this operator defines what the M\_LET macro supports. In C11, you can use API\_1(M\_INIT\_WITH\_THROUGH\_EMPLACE\_TYPE) as method to automatically use the different emplace functions defined in EMPLACE\_TYPE through a _Generic switch case. The EMPLACE\_TYPE shall use the LIST format. See emplace chapter.
|
||||
* SWAP(objd, objc): Swap the states of the object 'objc' and the object 'objd'. The objects shall use the same allocator.
|
||||
@@ -684,7 +692,7 @@ Properties can be stored in a sub-oplist format in the PROPERTIES operator.
|
||||
|
||||
The following properties are defined:
|
||||
* LET\_AS\_INIT\_WITH(1): Defined if the macro M\_LET shall always initialize the object with INIT\_WITH regardless of the given input. The value of the property is 1 (enabled) or 0 (disabled/default).
|
||||
* NOCLEAR(1): Defined if the object CLEAR operator can be ommited (like for basic types or POD data). The value of the property is 1 (enabled) or 0 (disabled/default).
|
||||
* NOCLEAR(1): Defined if the object CLEAR operator can be omitted (like for basic types or POD data). The value of the property is 1 (enabled) or 0 (disabled/default).
|
||||
|
||||
More properties are expected.
|
||||
|
||||
@@ -771,7 +779,7 @@ Let's take the interface of a pseudo library:
|
||||
```
|
||||
The library returns a pointer to the object, so we need API_4 for these methods.
|
||||
There is no method for the SET operator available. However, we can use the macro M_SET_THROUGH_INIT_SET
|
||||
to emulate a SET semantics by using a combinaison of CLEAR+INIT_SET. This enables to support
|
||||
to emulate a SET semantics by using a combination of CLEAR+INIT_SET. This enables to support
|
||||
the type for array containers in particular. Or we can avoid this definition if we don't need it.
|
||||
A basic oplist will be:
|
||||
|
||||
@@ -837,7 +845,7 @@ An operator OP can be defined, omitted or disabled:
|
||||
* ( ): the operator OP is omitted, and the default global operation for OP is used (if it exists).
|
||||
* ( OP(0) ): the operator OP is disabled, and it can never be used.
|
||||
|
||||
This can be usefull to disable an operator in an inherited oplist.
|
||||
This can be useful to disable an operator in an inherited oplist.
|
||||
|
||||
|
||||
### Which OPLIST to use?
|
||||
@@ -876,7 +884,7 @@ For example, internally M\_BOOL\_OPLIST inherits from M\_BASIC\_OPLIST.
|
||||
A typical example is if you want to provide the OOR\_SET and OOR\_EQUAL operators to a type
|
||||
so that it can be used in an OA dict.
|
||||
To do it, you use the M\_OPEXTEND macro. It takes as first argument the oplist you want to inherit with,
|
||||
and then you provide the additionals associations between operators to methods you want to add
|
||||
and then you provide the additional associations between operators to methods you want to add
|
||||
or override in the inherited oplist. For example:
|
||||
|
||||
```C
|
||||
@@ -910,7 +918,7 @@ Let's take a look at the interface of the FILE interface:
|
||||
FILE *fopen(const char *filename, const char *mode);
|
||||
fclose(FILE *f);
|
||||
```
|
||||
There is no INIT operator (an argument is mandatary), no INIT\_SET operator.
|
||||
There is no INIT operator (an argument is mandatory), no INIT\_SET operator.
|
||||
It is only possible to open a file from a filename.
|
||||
'FILE *' contains some space, so an alias is needed.
|
||||
There is an optional mode argument, which is a constant string, and isn't a valid preprocessing token.
|
||||
@@ -940,9 +948,9 @@ In which case, this enables you to close the file even if an exception is thrown
|
||||
|
||||
Memory Allocation functions can be globally set by overriding the following macros before using the definition \_DEF macros:
|
||||
|
||||
* M\_MEMORY\_ALLOC (type): return a pointer to a new object of type 'type'.
|
||||
* M\_MEMORY\_ALLOC (type) --> ptr: return a pointer to a new object of type 'type'.
|
||||
* M\_MEMORY\_DEL (ptr): free the single object pointed by 'ptr'.
|
||||
* M\_MEMORY\_REALLOC (type, ptr, number): return a pointer to an array of 'number' objects of type 'type', reusing the old array pointed by 'ptr'. 'ptr' can be NULL, in that case the array will be created.
|
||||
* M\_MEMORY\_REALLOC (type, ptr, number) --> ptr: return a pointer to an array of 'number' objects of type 'type', reusing the old array pointed by 'ptr'. 'ptr' can be NULL, in which case the array will be created.
|
||||
* M\_MEMORY\_FREE (ptr): free the array of objects pointed by 'ptr'.
|
||||
|
||||
ALLOC & DEL operators are supposed to allocate fixed size single element object (no array).
|
||||
@@ -5702,6 +5710,14 @@ It returns -1 in case of error in decoding the UTF8 string.
|
||||
|
||||
Return the position in the stream of the iterator 'it'.
|
||||
|
||||
##### void string\_it\_set\_ref(string\_it\_t it, string\_t str, string\_unicode\_t u)
|
||||
|
||||
Replace the unicode code point referenced by 'it' to the unicode code point 'u'
|
||||
in the string 'str'.
|
||||
If 'u' is 0, then it will resize the string to the size of the referenced iterator
|
||||
only keeping the unicode code points before the iterator.
|
||||
'it' shall be a valid iterator of 'str'.
|
||||
|
||||
##### bool string\_it\_equal\_p (const string\_it\_t it1, const string\_it\_t it2)
|
||||
|
||||
Return true if both iterators reference the same position, false otherwise.
|
||||
@@ -5711,6 +5727,13 @@ Return true if both iterators reference the same position, false otherwise.
|
||||
Push the unicode code point 'u' into the string 'str'
|
||||
encoding it as a variable UTF8 encoded code point.
|
||||
|
||||
##### bool string\_pop\_u (string\_unicode\_t *u, string\_t str)
|
||||
|
||||
Pop the last unicode code point from the string 'str'
|
||||
encoded as a variable UTF8 encoded code point
|
||||
and store in '*u' the popped unicode code point if 'u' is not NULL.
|
||||
It returns true in case of success or false otherwise (no character to pop or no valid UTF8).
|
||||
|
||||
##### size\_t string\_length\_u(string\_t str)
|
||||
|
||||
Return the number of UTF8 encoded code point in the string.
|
||||
@@ -5731,8 +5754,107 @@ The oplist of a string\_t
|
||||
|
||||
##### BOUNDED\_STRING\_DEF(name, size)
|
||||
|
||||
aka char[size+1]
|
||||
TODO: Document the API.
|
||||
Define a bounded string of size 'size', aka char[size+1] (including the final nul char).
|
||||
|
||||
###### Created types
|
||||
|
||||
The following types are automatically defined by the previous definition macro if not provided by the user:
|
||||
|
||||
####### name\_t
|
||||
|
||||
Type of the concurrent container of 'type'.
|
||||
|
||||
####### Generic methods
|
||||
|
||||
The following methods of the generic interface are defined (See generic interface for details):
|
||||
|
||||
* void name\_init(name\_t bounded\_string)
|
||||
* void name\_init\_set(name\_t bounded\_string, const name\_t src)
|
||||
* void name\_set(name\_t bounded\_string, const name\_t src)
|
||||
* void name\_reset(name\_t bounded\_string)
|
||||
* void name\_clear(name\_t bounded\_string)
|
||||
* size\_t name\_size(const name\_t bounded\_string)
|
||||
* size\_t name\_capacity(const name\_t bounded\_string)
|
||||
* bool name\_empty\_p(const name\_t bounded\_string)
|
||||
* void name\_get\_str(string\_t str, name\_t bounded\_string, bool append)
|
||||
* void name\_out\_str(FILE *file, name\_t bounded\_string)
|
||||
* bool name\_parse\_str(name\_t bounded\_string, const char str[], const char **end)
|
||||
* bool name\_in\_str(name\_t bounded\_string, FILE *file)
|
||||
* m\_serial\_return\_code\_t name\_out\_serial(m\_serial\_write\_t serial, const name\_t bounded\_string)
|
||||
* m\_serial\_return\_code\_t name\_in\_str(name\_t bounded\_string, m\_serial\_read\_t serial)
|
||||
* bool name\_equal\_p(name\_t bounded\_string1, name\_t bounded\_string2)
|
||||
* int name\_cmp(const name\_t bounded\_string1, const name\_t bounded\_string2)
|
||||
* size\_t name\_hash(name\_t bounded\_string)
|
||||
|
||||
####### Specialized methods
|
||||
|
||||
The following specialized methods are automatically created by the previous definition macro:
|
||||
|
||||
####### void name\_init\_set\_cstr)(bounded\_t string, const char str[])
|
||||
|
||||
Initialize the bounded string to the given C string 'str', truncating if needed.
|
||||
|
||||
####### void name\_set\_cstr)(bounded\_t string, const char str[])
|
||||
|
||||
Set the bounded string 'string' to the given C string 'str', truncating if needed.
|
||||
|
||||
####### void name\_set\_cstrn)(bounded\_t string, const char str[], size\_t n)
|
||||
|
||||
Set the bounded string 'string' to the 'n' first byte characters of the given C string 'str', truncating if needed.
|
||||
|
||||
####### void name\_set\_n)(bounded\_t string, const bounded\_t string, size\_t offset, size\_t length)
|
||||
|
||||
Set the bounded string 'string' to the 'length' first byte characters from the offset 'offset'
|
||||
of the bounded given C string 'str', truncating if needed.
|
||||
|
||||
####### const char *name\_get\_cstr)(const bounded\_t string)
|
||||
|
||||
Return the C string representation of the bounded string.
|
||||
|
||||
####### char name\_get\_char(const bounded\_t string, size\_t index)
|
||||
|
||||
Return the byte character at the given index of the string.
|
||||
index shall be within the size of the string.
|
||||
|
||||
####### void name\_cat)(bounded\_t string, const bounded_t str)
|
||||
####### void name\_cat\_cstr)(bounded\_t string, const char str[])
|
||||
|
||||
Concat the given C string to the bounded string.
|
||||
|
||||
####### int name\_cmp\_cstr)(const bounded\_t string, const char str[])
|
||||
|
||||
Compared the bounded string to the given C string:
|
||||
return a negative integer if the bounded string is before the C string,
|
||||
0 if there are equals,
|
||||
a positive integer otherwise.
|
||||
|
||||
####### bool name\_equal\_cstr\_p)(const bounded\_t string, const char str[])
|
||||
|
||||
Return true if the bounded string is equal to the given C string.*
|
||||
|
||||
####### int name\_printf)(bounded\_t string, const char format[], ...)
|
||||
|
||||
Set the bounded string to the format C string.
|
||||
|
||||
####### int name\_cat\_printf)(bounded\_t string, const char format[], ...)
|
||||
|
||||
Concat to the bounded string the format C string.
|
||||
|
||||
####### bool name\_fgets)(bounded\_t string, FILE *f, string\_fgets\_t arg)
|
||||
|
||||
Read at most 'max\_size+1' bytes from the file 'f' and set the bounded string to it.
|
||||
|
||||
####### bool name\_fputs)(FILE *f, const bounded\_t string)
|
||||
|
||||
Put the bounded string to the file 'f'.
|
||||
|
||||
####### bool name\_oor\_equal\_p)(const bounded\_t string, unsigned char n)
|
||||
|
||||
Provide the OOR\_EQUAL\_P method of a string.
|
||||
|
||||
####### void name\_oor\_set)(bounded\_t string, unsigned char n)
|
||||
|
||||
Provide the OOR\_SET method of a string.
|
||||
|
||||
|
||||
### M-CORE
|
||||
@@ -6542,12 +6664,12 @@ right initialization function in function of the type of argument.
|
||||
|
||||
The EMPLACE\_TYPE shall use a LIST based format for listing the different emplace types.
|
||||
This method is compatible with C11 or above.
|
||||
This method shall be used with API\_1 adaptator.
|
||||
This method shall be used with API\_1 adapter.
|
||||
|
||||
##### M\_SET\_THROUGH\_INIT\_SET(oplist, dest, src)
|
||||
|
||||
Emulate the SET semantics using a combinaison of CLEAR and INIT\_SET of the given oplist.
|
||||
This method shall be used with API\_1 adaptator.
|
||||
Emulate the SET semantics using a combination of CLEAR and INIT\_SET of the given oplist.
|
||||
This method shall be used with API\_1 adapter.
|
||||
|
||||
##### M\_GLOBAL\_OPLIST(a)
|
||||
|
||||
@@ -6683,7 +6805,7 @@ You can chain the M\_LET\_IF macro to create several different variables.
|
||||
|
||||
This macro registers the execution of 'clear\_code' when reaching
|
||||
the further closing brace of the next block of instruction.
|
||||
clear_code shall be a valid expression.
|
||||
clear\_code shall be a valid expression.
|
||||
|
||||
There shall be at most one M\_DEFER macro per line of source code.
|
||||
|
||||
@@ -6702,6 +6824,77 @@ You can use the break instruction to quit the block
|
||||
(the clear\_code will be executed) or you can use exception.
|
||||
|
||||
|
||||
##### M\_CHAIN\_INIT(name, init\_code, clear\_code)
|
||||
|
||||
This macro executes 'init\_code' then
|
||||
registers the execution of 'clear\_code' if an exception is triggered
|
||||
until the further closing brace of the next block of instruction.
|
||||
init\_code and clear\_code shall be a valid expression.
|
||||
If exception are not enabled, it simply executes 'init\_code'.
|
||||
|
||||
name shall a unique identifier in the current block.
|
||||
It can be chained multiple times to register multiple registrations.
|
||||
|
||||
Therefore it enables support for chaining
|
||||
initialization at the begining of a constructor for the fields of the constructed
|
||||
object so that even if the constructor failed and throw an exception,
|
||||
the fields of the constructed object are properly cleared.
|
||||
|
||||
This is equivalent to C++ construct:
|
||||
|
||||
void type() : field1(), field2() { rest of constructor }
|
||||
|
||||
M_CHAIN_INIT / M_CHAIN_OBJ shall be the first instructions of the constructor function.
|
||||
|
||||
Example:
|
||||
|
||||
void struct_init_set(struct_t d, struct_t s)
|
||||
{
|
||||
M_CHAIN_INIT(s1, string_init_set(d->s1, s->s1), string_clear(d->s1) )
|
||||
M_CHAIN_INIT(s2, string_init_set(d->s2, s->s2), string_clear(d->s2) ) {
|
||||
d->num = s->num;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##### M\_CHAIN\_OBJ(name, oplist, var [, value])
|
||||
|
||||
This macro executes the initialization method if 'var' to initialize it then
|
||||
registers the execution of its CLEAR method if an exception is triggered
|
||||
(and if the property NOCLEAR of the oplist is not defined)
|
||||
until the further closing brace of the next block of instruction.
|
||||
If exception are not enabled, it simply executes the initialization method.
|
||||
|
||||
The initialization method being used is :
|
||||
|
||||
* INIT method if there is no value
|
||||
* INIT\_SET method if there is a value which is not between parenthesis
|
||||
* INIT\_WITH method if there is a value which is between parenthesis.
|
||||
|
||||
name shall a unique identifier in the current block.
|
||||
It can be chained multiple times to register multiple registrations.
|
||||
|
||||
Therefore it enables support for chaining
|
||||
initialization at the begining of a constructor for the fields of the constructed
|
||||
object so that even if the constructor failed and throw an exception,
|
||||
the fields of the constructed object are properly cleared.
|
||||
|
||||
This is equivalent to C++ construct:
|
||||
|
||||
void type() : field1(), field2() { rest of constructor }
|
||||
|
||||
M_CHAIN_INIT / M_CHAIN_OBJ shall be the first instructions of the constructor function.
|
||||
|
||||
Example:
|
||||
|
||||
void struct_init_set(struct_t d, struct_t s)
|
||||
{
|
||||
M_CHAIN_OBJ(s1, STRING_OPLIST, d->s1, s->s1)
|
||||
M_CHAIN_OBJ(s2, STRING_OPLIST, d->s2, s->s2)
|
||||
M_CHAIN_OBJ(nu, M_BASIC_OPLIST, d->num, s->num) { }
|
||||
}
|
||||
|
||||
|
||||
#### Memory / Error macros
|
||||
|
||||
All these macro can be overridden before including the header m-core.h
|
||||
@@ -6851,7 +7044,7 @@ wanted serialization.
|
||||
* data: a table of M\_SERIAL\_MAX\_DATA\_SIZE of C types (Boolean, integer, size or pointer).
|
||||
This data is used to store the needed data for the methods.
|
||||
|
||||
This is pretty much like a pure virtual interface object in C++. The interface has to defines
|
||||
This is pretty much like a pure virtual interface object in C++. The interface has to define
|
||||
the following fields with the following definition:
|
||||
|
||||
* read\_boolean:
|
||||
@@ -6872,11 +7065,12 @@ the following fields with the following definition:
|
||||
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise
|
||||
* read\_array\_start:
|
||||
Start reading from the stream 'serial' an array (which is defined as a sequential collection of object).
|
||||
Set '*num' with the number of elements, or 0 if it is not known.
|
||||
Set '*num' with the number of elements, or (size\_t)-1 if it is not known.
|
||||
Initialize the object 'local' so that it can be used by the serialization object to serialize the array.
|
||||
('local' is an unique local serialization object of the array).
|
||||
Return M\_SERIAL\_OK\_CONTINUE if it succeeds and the parsing of the array can continue (the array is not empty),
|
||||
M\_SERIAL\_OK\_DONE if it succeeds and the array ends (the array is empty),
|
||||
M\_SERIAL\_FAIL\_RETRY if it doesn't support unknown number of elements,
|
||||
M\_SERIAL\_FAIL otherwise.
|
||||
* read\_array\_next:
|
||||
Continue reading from the stream 'serial' an array using 'local' to load / save data if needed.
|
||||
@@ -7081,11 +7275,12 @@ See [m-serial-json.h](#m-serial-json) for example of use.
|
||||
### M-THREAD
|
||||
|
||||
This header is for providing very thin layer around OS implementation of threads, conditional variables and mutex.
|
||||
It has back-ends for WIN32, POSIX thread or C11 thread.
|
||||
It has back-ends for WIN32, POSIX thread, FreeRTOS tasks or C11 thread.
|
||||
|
||||
It was needed due to the low adoption rate of the C11 equivalent layer.
|
||||
|
||||
It uses the C11 threads.h if possible.
|
||||
It uses the FreeRTOS tasks is it detects FreeRTOS.
|
||||
Otherwise it uses the C11 threads.h if possible.
|
||||
If the C11 implementation does not respect the C standard
|
||||
(i.e. the compiler targets C11 mode,
|
||||
the \_\_STDC\_NO\_THREADS\_\_ macro is not defined
|
||||
@@ -7096,6 +7291,12 @@ macro to select the back end to use:
|
||||
* 1: for C11
|
||||
* 2: for WINDOWS
|
||||
* 3: for PTHREAD
|
||||
* 4: for FreeRTOS
|
||||
|
||||
The FreeRTOS backend uses two additional global configuration constants:
|
||||
|
||||
* M\_USE\_TASK\_STACK\_SIZE to define the stack size of a thread (default is the minimal)
|
||||
* M\_USE\_TASK\_PRIORITY to define the priority of a thread (default is lowest).
|
||||
|
||||
Example:
|
||||
|
||||
@@ -7126,64 +7327,63 @@ The following methods are available:
|
||||
|
||||
A type representing a mutex.
|
||||
|
||||
##### void m\_mutex\_init(mutex)
|
||||
##### void m\_mutex\_init(m\_mutex\_t mutex)
|
||||
|
||||
Initialize the variable mutex of type m\_mutex\_t.
|
||||
Initialize the variable mutex and sets it to the unlocked position.
|
||||
If the initialization fails, the program aborts.
|
||||
Only one thread shall initialize the mutex.
|
||||
|
||||
##### void m\_mutex\_clear(mutex)
|
||||
##### void m\_mutex\_clear(m\_mutex\_t mutex)
|
||||
|
||||
Clear the variable mutex of type m\_mutex\_t.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
Clear the variable mutex.
|
||||
Only one thread shall clear the mutex.
|
||||
|
||||
##### void m\_mutex\_lock(mutex)
|
||||
##### void m\_mutex\_lock(m\_mutex\_t mutex)
|
||||
|
||||
Lock the variable mutex of type m\_mutex\_t for exclusive use.
|
||||
If the variable is not free, it will wait indefinitely until it is.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
Lock the variable mutex for exclusive use.
|
||||
If the mutex is not unlocked, it will wait indefinitely until it is.
|
||||
The mutex shall not be already locked.
|
||||
|
||||
##### void m\_mutex\_unlock(mutex)
|
||||
##### void m\_mutex\_unlock(m\_mutex\_t mutex)
|
||||
|
||||
Unlock the variable mutex of type m\_mutex\_t for exclusive use.
|
||||
If the variable is not locked, the behavior is undefined.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
Unlock the variable mutex for exclusive use.
|
||||
The mutex shall not be already unlocked.
|
||||
|
||||
#### m\_cond\_t
|
||||
|
||||
A type representing a conditional variable, used within a mutex section.
|
||||
A type representing a conditional variable, which shall be used within a mutex section.
|
||||
|
||||
##### void m\_cond\_init(m\_cond\_t cond)
|
||||
|
||||
Initialize the conditional variable cond of type m\_cond\_t.
|
||||
Initialize the conditional variable cond.
|
||||
If the initialization failed, the program aborts.
|
||||
Only one thread shall init the conditional variable.
|
||||
|
||||
##### void m\_cond\_clear(m\_cond\_t cond)
|
||||
|
||||
Clear the variable cond of type m\_cond\_t.
|
||||
Clear the variable cond.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
Only one thread shall clear the conditional variable.
|
||||
|
||||
##### void m\_cond\_signal(m\_cond\_t cond)
|
||||
|
||||
Within a mutex exclusive section,
|
||||
signal that the event associated to the variable cond of type m\_cond\_t
|
||||
Signal that the event associated to the variable cond
|
||||
has occurred to at least a single thread.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
All usage of this conditional variable shall be done within the same mutex exclusve section.
|
||||
|
||||
##### void m\_cond\_broadcast(m\_cond\_t cond)
|
||||
|
||||
Within a mutex exclusive section,
|
||||
signal that the event associated to the variable cond of type m\_cond\_t
|
||||
Signal that the event associated to the variable cond
|
||||
has occurred to all waiting threads.
|
||||
If the variable is not initialized, the behavior is undefined.
|
||||
All usage of this conditional variable shall be done within the same mutex exclusve section.
|
||||
|
||||
##### void m\_cond\_wait(m\_cond\_t cond, m\_mutex\_t mutex)
|
||||
|
||||
Within a mutex exclusive section defined by mutex,
|
||||
wait indefinitely for the event associated to the variable cond of type m\_cond\_t
|
||||
Wait indefinitely for the event associated to the variable cond
|
||||
to occur.
|
||||
IF multiple threads wait for the same event, which thread to awoken
|
||||
is not specified.
|
||||
If any variable is not initialized, the behavior is undefined.
|
||||
All usage of this conditional variable shall be done within the mutex exclusve section.
|
||||
|
||||
#### m\_thread\_t
|
||||
|
||||
@@ -7890,16 +8090,16 @@ that accept the generic interface (mainly \_call).
|
||||
### M-TRY
|
||||
|
||||
This header is for [exception handling](https://en.wikipedia.org/wiki/Exception_handling).
|
||||
It provides basic functionnality for throwing exception and catching then.
|
||||
It provides basic functionality for throwing exception and catching then.
|
||||
The setjmp and longjmp standard library functions (or some variants) are used to implement the try / catch / throw macro keywords.
|
||||
It doesn't support the finaly keyword.
|
||||
It doesn't support the finally keyword.
|
||||
When building with a C++ compiler, theses macro keywords simply use the original C++ keyword in a way to match
|
||||
the specification below.
|
||||
|
||||
The whole program shall be compiled with the same exact compiler and the same target architecture.
|
||||
|
||||
Only one type of data is supported as exception. This is done to simplify the design and to force using exception
|
||||
as a general purpose error handlings. It should only be used for rare case of errors which cannot be dealt locally
|
||||
Only one type of data is supported as exception. This is done to simplify the design and to avoid using exception
|
||||
as a general purpose error mecanism. It should only be used for rare case of errors which cannot be dealt locally
|
||||
in the program being executed.
|
||||
|
||||
In order to support [Resource Acquisition Is Initialization](https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)
|
||||
@@ -7937,6 +8137,11 @@ otherwise it will compile in degraded mode:
|
||||
|
||||
-fblocks -lBlocksRuntime
|
||||
|
||||
When writing your own constructor, you should consider M\_CHAIN\_INIT
|
||||
to support partially constructed object
|
||||
if there are more than two source of throwing in your object
|
||||
(any memory allocation is a source of throwing).
|
||||
|
||||
#### struct m\_exception\_s
|
||||
|
||||
This is the exception type. It is composed of the following fields:
|
||||
@@ -8319,6 +8524,45 @@ Use fast integer conversion algorithms instead of using the LIBC.
|
||||
|
||||
Default value: 1 (because it also generates smaller code).
|
||||
|
||||
#### M\_USE\_DECL
|
||||
|
||||
If M\_USE\_FINE\_GRAINED\_LINKAGE is not defined,
|
||||
it will request M\*LIB to change the linkage of its symbols globally:
|
||||
instead of inlining the functions, it will emit weak symbols
|
||||
for the functions that are not inlined.
|
||||
|
||||
And in exactly one translation unit, the macro M\_USE\_DEF
|
||||
should also be defined so that it emits the normal definition
|
||||
of the functions. In which case, it should contain all symbols
|
||||
used by all other translation units.
|
||||
|
||||
You should compile your program with
|
||||
-ffunction-sections -fdata-sections
|
||||
and link with
|
||||
-Wl,--gc-sections
|
||||
in order to remove unused code and to merge identical code
|
||||
otherwise it is likely to generate even bigger code than using the inlining linkage.
|
||||
|
||||
This works for GCC / CLANG in C mode.
|
||||
|
||||
#### M\_USE\_FINE\_GRAINED\_LINKAGE
|
||||
|
||||
It will request M\*LIB to change the linkage of its symbols dynamically at compile time:
|
||||
in which case
|
||||
M\_USE\_DECL / M\_USE\_DEF can be defined / undefined several times in a translation unit
|
||||
and M\*LIB will emit the change the linkage of the symbols being declared accordingly:
|
||||
|
||||
* definition like if M\_USE\_DECL and M\_USE\_DEF are defined
|
||||
* declaration like if M\_USE\_DECL is defined
|
||||
* inline like otherwise
|
||||
|
||||
This enables to inline some functions and not others.
|
||||
|
||||
M\_USE\_DECL / M\_USE\_DEF shall be defined without effective value.
|
||||
|
||||
See M\_USE\_DECL for more details.
|
||||
|
||||
|
||||
#### M\_MEMORY\_ALLOC
|
||||
|
||||
See [m-core.h](#m-core)
|
||||
|
||||
+251
-32
@@ -1,5 +1,206 @@
|
||||
*Long term issues*
|
||||
------------------
|
||||
==========================================================
|
||||
|
||||
* TODO #33 : Handling of partially constructed object :ANOMALY:
|
||||
|
||||
** State
|
||||
|
||||
Support of partially constructed object needs special code to handle it
|
||||
correctly (register a correct cleanup function in case of exception).
|
||||
|
||||
Current containers don't support such features.
|
||||
|
||||
** Actions
|
||||
|
||||
Add such support in M*LIB containers.
|
||||
|
||||
It can be difficult. For example, for array _init_set
|
||||
function due to the copy of the object one per one. Each copied sub object
|
||||
may throw an exception, so we always need to have the container in a correct
|
||||
state so that it can be cleanup.
|
||||
|
||||
* TODO #32 : User specialization fields in the container :ENHANCEMENT:
|
||||
|
||||
** State
|
||||
|
||||
Some methods of a contained object may need to have some options that
|
||||
are neither constant nor global, but are specialized in function of the container.
|
||||
|
||||
For example, a memory handler may need a parameter which is needed to identify
|
||||
which pool of memory has to be used.
|
||||
|
||||
** Plan:
|
||||
|
||||
Add a new operator "CONTEXT" which is a type to be added in the
|
||||
defined container. Then it can be accessed by the operator through an extension
|
||||
of the GAIA by adding support for identification of specialization like this:
|
||||
|
||||
( CONTEXT( memory_pool_ref ),
|
||||
NEW( API(NONE, memory_pool_alloc, CONTEXT, ARG1)),
|
||||
DEL( API(NONE, memory_pool_free, CONTEXT, ARG1)) )
|
||||
|
||||
** Open points:
|
||||
|
||||
- How to get access to the specialization field of the container? ==> Define the "self" name as the name of the container for all methods? What to do when there are several containers for a method?
|
||||
- How to initialize the specialization field of the container? provide custom initialization functions? It seems to be the hard point.
|
||||
|
||||
* TODO #31 : Uniformize parametrisation options of containers :ENHANCEMENT:
|
||||
|
||||
** State
|
||||
|
||||
Currently in order to pass some parametrization of the containers,
|
||||
the parameters are passed to the generation macros through:
|
||||
|
||||
- extra parameters of the macros,
|
||||
- special operators of the contained object oplist.
|
||||
|
||||
The extra parameters of some generation macros break the uniformity
|
||||
of the interface.
|
||||
It is conceptually wrong to put some special operators of the contained object
|
||||
that have only meanings for the container object.
|
||||
In case of adding new options, it break the existing interface or put another
|
||||
operator in the contained object oplist.
|
||||
|
||||
|
||||
The following parameters are used:
|
||||
|
||||
- Fixed size of a queue (buffer / B+Tree),
|
||||
- Policy of a queue (buffer),
|
||||
- Type of the container, IT type of the container, Ref type of the iterator
|
||||
|
||||
The following operators are used:
|
||||
|
||||
- NEW / DEL / REALLOC / FREE
|
||||
- MEMPOOL / MEMPOOL_LINKAGE
|
||||
|
||||
The following new options is planned:
|
||||
|
||||
- Interface (See #28)
|
||||
- Extra parameter for memory allocation function
|
||||
|
||||
** Plan
|
||||
|
||||
The M\_*\_DEF\_AS macros shall be changed like this:
|
||||
|
||||
M_*_DEF_AS(name, cont_oplist, type[, type_oplist])
|
||||
|
||||
with cont\_oplist being the container oplist that gives parametrization to the container definition.
|
||||
The following operators are planned:
|
||||
|
||||
- TYPE: to define the type of the container,
|
||||
- IT\_TYPE: to define the IT type of the container,
|
||||
- SUBTYPE: to define the type pointed by the iterator,
|
||||
- FIXED\_SIZE: to define the fixed size of a container,
|
||||
- POLICY: to define the policy of a container,
|
||||
- NEW / DEL / REALLOC / FREE: to define the memory interface,
|
||||
- MEMPOOL / MEMPOOL_LINKAGE: to request a definition of a specialized memory interface,
|
||||
- INTERFACE: to request a pure header definition, an implementation or both (see #28),
|
||||
- CONTEXT: to request an extra context parameter to add in the container.
|
||||
|
||||
All operators should be optional.
|
||||
|
||||
The NEW / DEL / REALLOC / FREE / MEMPOOL / MEMPOOL_LINKAGE won't have any effects anymore if defined in the contained object oplist.
|
||||
|
||||
** Pro:
|
||||
|
||||
- Uniformize interface
|
||||
|
||||
** Con:
|
||||
|
||||
- API breakage. It can be mitigated by providing an adaptating layer by prividing the new interface for M\_*\_DEF\_AS only
|
||||
and *\_DEF\_AS will provide a translation layer.
|
||||
|
||||
* TODO #30 : Serialization rework :ENHANCEMENT:
|
||||
|
||||
** State
|
||||
Currently, each container supports 3 serialization methods:
|
||||
|
||||
- old format to FILE
|
||||
- old format to string
|
||||
- generic serialization
|
||||
|
||||
Generic serialiation connect the container format to the serialization object constraints.
|
||||
It is done through a vtable. As such there is a performance penality and it avoids proper inlining.
|
||||
|
||||
** Evolution
|
||||
|
||||
Old format should be deprecated and shall use the generic serialization interface.
|
||||
|
||||
Serialization object shall provide an OPLIST of serialization.
|
||||
For example CORE will provide OLD Format oplist and serial-json will provide JSON format oplist.
|
||||
Each oplist will provide the suffix needed for the serialization, and the interface
|
||||
(see already existing interface).
|
||||
|
||||
Then a container will generate specialized serialization methods for each provided oplist.
|
||||
|
||||
Pros:
|
||||
|
||||
- Faster
|
||||
- In the M*LIB philosphy: much like other oplist usage.
|
||||
|
||||
Cons:
|
||||
|
||||
- compatibility breakage.
|
||||
|
||||
Open point:
|
||||
|
||||
- how can a user add a new serialization object?
|
||||
- Can we make a generic serialization object to support migration path?
|
||||
|
||||
** Example
|
||||
|
||||
serial-json provides
|
||||
|
||||
#define M_SERIAL_1() (NAME(_json), READ_INT(...), WRITE_INT(...) )
|
||||
|
||||
containers provides
|
||||
|
||||
For i in 1 100 ; do
|
||||
if do exist M_SERIAL_ ## i ()
|
||||
expand(SERIAL_METHOD with M_SERIAL_1())
|
||||
|
||||
SERIAL_METHOD(name, ....)
|
||||
static inline m_serial_return_code_t \
|
||||
M_C(M_F(name, _out_serial),M_GET_NAME(serial_op) )(M_GET_TYPE(serial_op) f, const list_t list) \
|
||||
|
||||
* DONE #29 : Support of partial initialized object :ANOMALY:
|
||||
|
||||
** State
|
||||
|
||||
In case of exception during the construction of an object,
|
||||
if the object is partially constructed, there is no destructor to call.
|
||||
Therefore if there is some partially constructed object
|
||||
(with some fields already fully constructed), there will be some links.
|
||||
This is the same problem with C++
|
||||
|
||||
** Proposition
|
||||
|
||||
Provide new macros to perform the partial initialization before doing the remaining taf.
|
||||
Something like:
|
||||
|
||||
M_CHAIN_INIT( init_code, clear_code)
|
||||
|
||||
or
|
||||
|
||||
x is { string_t s; string_t d; int num; }
|
||||
|
||||
void struct_init_set(struct_t x, const struct_t y)
|
||||
{
|
||||
// First thing is Chained Initialization
|
||||
M_CHAIN_INIT( string_init_set(x->s, y->s), string_clear(x->s) );
|
||||
M_CHAIN_INIT( string_init_set(x->d, y->d), string_clear(x->d) );
|
||||
// End of chain init
|
||||
x->num = y->num;
|
||||
}
|
||||
|
||||
M_CHAIN_INIT will push the clean code pretty much like M_LET.
|
||||
Everything else is done in M_LET: when the constructor fully returns,
|
||||
the index of the clean code to call is reset to its value before calling
|
||||
the constructor. It means that the partially initialized code will be removed
|
||||
from this stack before the clean method of the structure itself is pushed.
|
||||
|
||||
If an exception is raised after a M_CHAIN_INIT, only the clean methods
|
||||
of the M_CHAIN_INIT are called.
|
||||
|
||||
* TODO #28 : Separate generation of interface to implementation :ENHANCEMENT:
|
||||
|
||||
@@ -9,9 +210,32 @@ and an implementation only for the source code.
|
||||
Try to keep API compatibility
|
||||
==> Only modify renamed macro with M_ prefix by giving a new mandatory
|
||||
argument for such generation.
|
||||
|
||||
|
||||
This argument is a generation parametric argument.
|
||||
oplist is a parameter that define the property of the contained type.
|
||||
It could be used to pass this information but it will be an abuse of interface.
|
||||
Another argument is needed.
|
||||
|
||||
Used arguments to parameter generation not related to the contained type:
|
||||
|
||||
- memory interface (NEW / DEL / ...)
|
||||
- queue policy
|
||||
- fixed size for queue
|
||||
- fixed node size for B+Tree
|
||||
- generate static inline, public (extern) or private (define) functions.
|
||||
- name of the type.
|
||||
- name of the iterator
|
||||
- name of the iterated element.
|
||||
- ...
|
||||
|
||||
Use another oplist as argument for M_.._DEF_AS (See #31)
|
||||
|
||||
M_BUFFER_DEF_AS(name, (TYPE(toto), FIXED_SIZE(10), POLICY(STACK), INTERFACE(header)), int, M_BASIC_OPLIST)
|
||||
|
||||
* TODO #27 : Uniformization of m-buffer interface :ENHANCEMENT:
|
||||
|
||||
** State
|
||||
|
||||
The m-buffer interface requires special argument to work:
|
||||
- size & policy for BUFFER,
|
||||
- policy only for the others.
|
||||
@@ -19,8 +243,10 @@ This is not uniform with the others generation macros and not uniform with each
|
||||
Moreover the others are the only one which can be used in a shared memory, so
|
||||
a fixed size will be good to have too for such interface.
|
||||
|
||||
==> Uniformize the interface. How?
|
||||
==> Provide static size for all QUEUE.
|
||||
** Plan
|
||||
|
||||
- Uniformization of the interface (See #31)
|
||||
- Provide static size for all QUEUE.
|
||||
|
||||
* TODO #26 : Hash-Map for huge objects :ENHANCEMENT:
|
||||
|
||||
@@ -60,7 +286,7 @@ unsigned get_small_hash(int64_t x) {
|
||||
Find a way to support error return code for the API in case of allocation
|
||||
failure.
|
||||
|
||||
Any service that returns void shall return a "int".
|
||||
Any service that returns void shall return a "int" (or another type).
|
||||
In case of allocation failure, it shall return an error.
|
||||
M_CALL macro shall stop its execution if the service returns an error code
|
||||
and the error code represents an error (avoid rewritting everything)
|
||||
@@ -119,19 +345,20 @@ RETCODE/RETCODE
|
||||
If really needed, the macro can be avoided and code can be hand written.
|
||||
|
||||
Open points:
|
||||
|
||||
- How to handle warnings on unused labels?
|
||||
- What about M_LET/ M_EACH?
|
||||
- What about M_LET / M_EACH? Maybe only supports those.
|
||||
|
||||
|
||||
* TODO #24 : New: Add MIN-MAX-HEAP container :ENHANCEMENT:
|
||||
* TODO #24 : New MIN-MAX-HEAP container :ENHANCEMENT:
|
||||
|
||||
See https://en.wikipedia.org/wiki/Min-max_heap
|
||||
as DPRIORITY_QUEUE_DEF ?
|
||||
|
||||
NOTE: Needs for such container?
|
||||
|
||||
* TODO #23 : Strict MOVE semantic to clarify :ENHANCEMENT:
|
||||
|
||||
* TODO #23: Strict MOVE semantic to clarify :ENHANCEMENT:
|
||||
** State
|
||||
|
||||
Some type may need to have a force MOVE semantic (for example, they can store
|
||||
pointer to themselves). Currently the INIT_MOVE & MOVE operators are more
|
||||
@@ -146,7 +373,7 @@ moving the data before they can be moved using MOVE. Two solutions:
|
||||
- New operator MOVE_SELF to fix a type after it has been moved.
|
||||
- If MOVE defined, force another table and then copy by hand the type. This will be slower and consumme more memory.
|
||||
|
||||
** MOVE in OPLIST :ENHANCEMENT:
|
||||
** MOVE in OPLIST
|
||||
|
||||
Proposal: do not export INIT_MOVE / MOVE operator in OPLIST if the MOVE operator is
|
||||
compatible with a pure COPY semantic. An exported MOVE operator will tell
|
||||
@@ -165,7 +392,6 @@ defined with [1] tricks but without an explicit INIT_MOVE / MOVE
|
||||
operators as it uses MOVE_DEFAULT which is not (fully compatible).
|
||||
==> Analyse limitation and possible constraint usages.
|
||||
|
||||
|
||||
Being able to define a correct default for INIT_MOVE will be really good
|
||||
(compatible with trivial move copy).
|
||||
In such case, all INIT_MOVE & MOVE operators can be removed from oplist
|
||||
@@ -176,12 +402,12 @@ If the type is typedef T t[1] then passing such an argument to a function,
|
||||
will transform the argument to T*, and the type of the argument doesn't match
|
||||
what is expecting resulting in a move of the pointers, not a move of the design data.
|
||||
|
||||
Defining a TYPE to this macro seems mandatory, but within restricting to C11
|
||||
(by using _Generic to detect such case),
|
||||
I don't see any way to define the macro.
|
||||
Defining this type seems possible with C11 _Generic and a TYPE in the oplist,
|
||||
but without C11 _Generic I don't see any way to define such macro.
|
||||
|
||||
Without a way to write such a macro, the ticket seems pretty much a dead end.
|
||||
|
||||
* TODO #20: New: Bucket priority queue :ENHANCEMENT:
|
||||
* TODO #20 : New: Bucket priority queue :ENHANCEMENT:
|
||||
|
||||
Add a new kind of priority queue.
|
||||
See https://en.wikipedia.org/wiki/Bucket_queue
|
||||
@@ -197,21 +423,18 @@ except that we can scan 64 entries at a time).
|
||||
Check if we can use BITSET, or introduce fixed size BITSET or use ad-hock
|
||||
implementation.
|
||||
|
||||
|
||||
* TODO #19: New: Intrusive Red Black Tree :ENHANCEMENT:
|
||||
* TODO #19 : New: Intrusive Red Black Tree :ENHANCEMENT:
|
||||
|
||||
Add intrusive red black tree.
|
||||
Look also for AVL tree (NOTE: Is there a performance difference between the two?)
|
||||
|
||||
|
||||
* TODO #18: Missing methods :ENHANCEMENT:
|
||||
* TODO #18 : Missing methods :ENHANCEMENT:
|
||||
|
||||
Some containers don't have all the methods they should.
|
||||
See the cells in yellow here:
|
||||
http://htmlpreview.github.io/?https://github.com/P-p-H-d/mlib/blob/master/doc/Container.html
|
||||
|
||||
|
||||
* TODO #17: New: Ressource handler :ENHANCEMENT:
|
||||
* TODO #17 : New: Ressource handler :ENHANCEMENT:
|
||||
|
||||
A global 'ressouce handler' which shall associated a unique handle to a ressource.
|
||||
The handle shall be unique for the ressource and shall not be reused.
|
||||
@@ -238,11 +461,10 @@ http://htmlpreview.github.io/?https://github.com/P-p-H-d/mlib/blob/master/doc/Co
|
||||
|
||||
How to handle multiple resource ?
|
||||
|
||||
* variant: works fine. Memory usage can be (much) higher than needed if there is a lot of dissimilarity between the size of the objects.
|
||||
* embedded the type in the ressource handler: more work, API more complex. Memory usage seems better.
|
||||
* variant: Pro : easy. Con: Memory usage can be (much) higher than needed if there is a lot of dissimilarity between the size of the objects.
|
||||
* embedded the type in the ressource handler: Con: more work, API more complex. Pro: Memory usage seems better.
|
||||
|
||||
|
||||
* TODO #16: New: Lock Free List :ENHANCEMENT:
|
||||
* TODO #16 : New: Lock Free List :ENHANCEMENT:
|
||||
|
||||
Implement a lock free list. Most of the difficulty is the memory reclamation part.
|
||||
Typically this lock free list shall be compatible with RCU method.
|
||||
@@ -265,8 +487,7 @@ http://htmlpreview.github.io/?https://github.com/P-p-H-d/mlib/blob/master/doc/Co
|
||||
- needs to be logically deleted : needs a previous field
|
||||
(NULL if not logically deleted) ? TBC
|
||||
|
||||
|
||||
* TODO #14: Memory allocation enhancement :ENHANCEMENT:
|
||||
* DONE #14 : Memory allocation enhancement :ENHANCEMENT:
|
||||
|
||||
Enhancement of the memory allocation scheme to find way to deal properly with advanced allocators:
|
||||
|
||||
@@ -300,8 +521,9 @@ Needs some formal operator in the oplist to support it fully and an example.
|
||||
|
||||
It is a kind of object inheritance where the container inherits some extra data from its base.
|
||||
|
||||
Duplicate with #32 which is more generic ==> Closed
|
||||
|
||||
* TODO #12: New: Atomic shared pointer :ENHANCEMENT:
|
||||
* TODO #12 : New: Atomic shared pointer :ENHANCEMENT:
|
||||
|
||||
Add an extension to the SHARED_PTR API:
|
||||
|
||||
@@ -375,9 +597,7 @@ Other alternative solution is to use the bit 0 to mark the pointer as being upda
|
||||
|
||||
Other implementation seems to have it hard to be lock-free: cf. https://github.com/llvm-mirror/libcxx/commit/5fec82dc0db3623546038e4a86baa44f749e554f
|
||||
|
||||
|
||||
|
||||
* TODO #5: New: Concurrent dictionary Container :ENHANCEMENT:
|
||||
* TODO #5 : New: Concurrent dictionary Container :ENHANCEMENT:
|
||||
|
||||
Implement a more efficient dictionary than lock + std dictionary for all operations when dealing with threads.
|
||||
See https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx
|
||||
@@ -423,7 +643,6 @@ It needs before lock-free list: http://www.cse.yorku.ca/~ruppert/papers/lfll.pdf
|
||||
Atomic update is done by allocating a new node, update it, and atomicaly store it in the dict, putting the old one as logically deleted and to reclaim later.
|
||||
(Other threads may still read its data so we cannot free immediatly).
|
||||
|
||||
|
||||
* DONE #22: Enhanced services for SPSC Queue :ENHANCEMENT:
|
||||
|
||||
Add services:
|
||||
|
||||
+15
-2
@@ -21,7 +21,7 @@
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
CC=cc -std=c99
|
||||
CFLAGS=-Wall -W -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wswitch-default -Wswitch-enum -Wcast-align -Wpointer-arith -Wbad-function-cast -Wstrict-overflow=5 -Wstrict-prototypes -Winline -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wunreachable-code -Wlogical-op -Wstrict-aliasing=2 -Wredundant-decls -Wold-style-definition -Wno-unused-function -g
|
||||
CFLAGS=-Wall -W -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wswitch-default -Wswitch-enum -Wcast-align -Wpointer-arith -Wbad-function-cast -Wstrict-overflow=5 -Wstrict-prototypes -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wunreachable-code -Wlogical-op -Wstrict-aliasing=2 -Wredundant-decls -Wold-style-definition -Wno-unused-function -g
|
||||
GMP_DIR=
|
||||
MPFR_DIR=$(GMP_DIR)
|
||||
CPPFLAGS=-I..
|
||||
@@ -33,18 +33,31 @@ RM=rm -f
|
||||
.c.exe:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@ `cat config` $(LDFLAGS)
|
||||
|
||||
.c.o:
|
||||
@$(MAKE) config
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -O2 `cat config.link` -DNDEBUG -g $< -c -o $@
|
||||
|
||||
all: config
|
||||
$(MAKE) `ls ex-*.c|sed -e 's/\.c/\.exe/g'`
|
||||
if test "$(CC)" = "cc -std=c99" ; then $(MAKE) `ls ex11-*.c|sed -e 's/\.c/\.exe/g'` CC="cc -std=c11" ; fi
|
||||
$(MAKE) exm.exe exn.exe
|
||||
|
||||
exm.exe: exm-lib.o exm-main.o
|
||||
$(CC) `cat config.link` -g $^ -o $@
|
||||
|
||||
exn.exe: exn-lib.o exn-main.o
|
||||
$(CC) `cat config.link` -g $^ -o $@
|
||||
|
||||
config:
|
||||
printf "#include <gmp.h>\nint main(void){mpz_t z; mpz_init(z); return 0;}\n" > config-test.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -I$(GMP_DIR)/include -L$(GMP_DIR)/lib config-test.c -lgmp -o config-test.exe $(LDFLAGS) 2> /dev/null && echo "-DHAVE_GMP=1 -DHAVE_MPFR=0 -I$(GMP_DIR)/include -L$(GMP_DIR)/lib -lgmp" > config || echo "-DHAVE_GMP=0 -DHAVE_MPFR=0 " > config
|
||||
printf "#include <mpfr.h>\nint main(void){mpfr_t z; mpfr_init(z); return 0;}\n" > config-test.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -I$(GMP_DIR)/include -I$(MPFR_DIR)/include -L$(GMP_DIR)/lib -L$(MPFR_DIR)/lib config-test.c -lmpfr -lgmp -o config-test.exe $(LDFLAGS) 2> /dev/null && echo "-DHAVE_GMP=1 -DHAVE_MPFR=1 -I$(GMP_DIR)/include -L$(GMP_DIR)/lib -I$(MPFR_DIR)/include -L$(MPFR_DIR)/lib -lmpfr -lgmp" > config || echo "MPFR not available"
|
||||
printf "#include <stdio.h>\nint main(void){printf(\"Ok\"); return 0;}\n" > config-test.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) config-test.c -ffunction-sections -fdata-sections -Wl,--gc-sections 2> /dev/null && echo "-ffunction-sections -fdata-sections -Wl,--gc-sections" > config.link || echo "" > config.link
|
||||
$(RM) config-test.c config-test.exe
|
||||
|
||||
clean:
|
||||
$(RM) *.exe *.s *~ *.o ./a.dat config
|
||||
$(RM) *.exe *.s *~ *.o ./a.dat config config.link
|
||||
|
||||
|
||||
+7
-7
@@ -4,16 +4,16 @@
|
||||
|
||||
/* Define a dynamic array of int */
|
||||
ARRAY_DEF(vector_int, int)
|
||||
/* Register the oplist of this dynamic array globally */
|
||||
/* Register the oplist of this dynamic array globally (using implicitely M_BASIC_OPLIST) */
|
||||
#define M_OPL_vector_int_t() ARRAY_OPLIST(vector_int)
|
||||
/* Define some standards algorithms on this dynamic array */
|
||||
/* Define some standards algorithms on this dynamic array. We can reuse the prefix of the dynamic array */
|
||||
ALGO_DEF(vector_int, vector_int_t)
|
||||
|
||||
/* Define a dynamic array of bool */
|
||||
ARRAY_DEF(vector_bool, bool)
|
||||
/* Register the oplist of this dynamic array globally */
|
||||
#define M_OPL_vector_bool_t() ARRAY_OPLIST(vector_bool, M_BOOL_OPLIST)
|
||||
/* Define some standards algorithms on this dynamic array */
|
||||
/* Define some standards algorithms on this dynamic array. We can reuse the prefix of the dynamic array */
|
||||
ALGO_DEF(vector_bool, vector_bool_t)
|
||||
|
||||
/* ID function */
|
||||
@@ -41,10 +41,10 @@ int main(void)
|
||||
#else
|
||||
for M_EACH(it, myvector, vector_int_t) {
|
||||
printf(" %d", *it);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
} /* End of M_LET: myvector & tmp are automaticly cleared */
|
||||
|
||||
// Same thing but with booleans
|
||||
M_LET(myvector, tmp, vector_bool_t) {
|
||||
@@ -56,13 +56,13 @@ int main(void)
|
||||
printf("myvector contains:");
|
||||
for M_EACH(it, myvector, vector_bool_t) {
|
||||
printf(" %d", (int)*it);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
printf ("ALL: %d ANY: %d NONE: %d\n",
|
||||
vector_bool_all_of_p(myvector, id),
|
||||
vector_bool_any_of_p(myvector, id),
|
||||
vector_bool_none_of_p(myvector, id) );
|
||||
}
|
||||
} /* End of M_LET: myvector & tmp are automaticly cleared */
|
||||
|
||||
return 0;
|
||||
}
|
||||
+5
-6
@@ -14,7 +14,7 @@ ARRAY_DEF(vector_int, int)
|
||||
/* Register the oplist of this array of integer globally */
|
||||
#define M_OPL_vector_int_t() ARRAY_OPLIST(vector_int)
|
||||
|
||||
/* Micro macro to detect if a string starts with the given pattern */
|
||||
/* Micro macro to detect if the key string starts with the given pattern */
|
||||
#define start_with(pattern, item) \
|
||||
string_start_with_str_p((item).key, (pattern))
|
||||
|
||||
@@ -26,11 +26,10 @@ int main(void)
|
||||
int s = 0;
|
||||
// Init keys as a vector_int_t, initialize it (and prepare its destruction)
|
||||
M_LET(keys, vector_int_t)
|
||||
// Initialize m as a dictionnary and initialize it with the given database
|
||||
// Initialize tmp as a dictionanry
|
||||
M_LET( (m, (STRING_CTE("foo"), 1), (STRING_CTE("bar"), 42), (STRING_CTE("bluez"), 7), (STRING_CTE("stop"), 789) ), tmp, dict_t) {
|
||||
|
||||
/* Extract all elements of 'm' that starts with 'b' */
|
||||
// Initialize m as a dictionnary and initialize it with the given database
|
||||
// Initialize tmp as a dictionnary
|
||||
M_LET( (m, (STRING_CTE("foo"), 1), (STRING_CTE("bar"), 42), (STRING_CTE("bluez"), 7), (STRING_CTE("stop"), 789) ), tmp, dict_t) {
|
||||
/* Extract all elements of 'm' that starts with 'b' and fills tmp with it */
|
||||
ALGO_EXTRACT(tmp, dict_t, m, dict_t, start_with, "b");
|
||||
/* Extract the values of theses elements */
|
||||
ALGO_TRANSFORM(keys, vector_int_t, tmp, dict_t, get_value);
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ int main(void)
|
||||
{
|
||||
// Let 's' be a string_t and initialize it.
|
||||
M_LET(s, string_t)
|
||||
// Let 'v' be a vector of integer and initialize it.
|
||||
M_LET( (v, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), vector_int_t) {
|
||||
// Let 'v' be a vector of integer and initialize it.
|
||||
M_LET( (v, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), vector_int_t) {
|
||||
int sum = 0, product = 0;
|
||||
|
||||
// Compute the sum of theses integers.
|
||||
|
||||
+22
-1
@@ -8,13 +8,17 @@
|
||||
#include "m-string.h"
|
||||
#include "m-algo.h"
|
||||
|
||||
// Let's create a list of string by using the M*LIB dynamic string.
|
||||
// Let's create a list of string by using the M*LIB dynamic string 'string_t'
|
||||
// The prefix used for generating functions will be 'list_string'
|
||||
LIST_DEF(list_string, string_t)
|
||||
|
||||
// Let's register the oplist globally so that other M*LIB macros
|
||||
// can get the oplist without us giving it explictly to them.
|
||||
// An oplist is the association of operators to the provided methods
|
||||
// so that generic code can use correctly an object of such type.
|
||||
// LIST_OPLIST is a macro used to generate the oplist associated to the
|
||||
// list itself. It needs the prefix used for generating the list (aka list_string here)
|
||||
// and the oplist of the item in the list (aka the string oplist)
|
||||
#define M_OPL_list_string_t() LIST_OPLIST(list_string, STRING_OPLIST)
|
||||
|
||||
// Let's define some basic algorithms over this list of string.
|
||||
@@ -95,6 +99,23 @@ int main(void)
|
||||
}
|
||||
|
||||
} // Everything is cleared after this point.
|
||||
|
||||
// Let's create another list of string and init it.
|
||||
list_string_t list;
|
||||
list_string_init(list);
|
||||
// Let's put some elements in it:
|
||||
list_string_emplace_back (list, "A");
|
||||
list_string_emplace_back (list, "B");
|
||||
list_string_emplace_back (list, "C");
|
||||
list_string_emplace_back (list, "D");
|
||||
// Reverse it
|
||||
list_string_reverse(list);
|
||||
// Let's display the string by serializing the elements of the list:
|
||||
printf ("List of string = ");
|
||||
list_string_out_str(stdout, list);
|
||||
printf ("\n");
|
||||
// Don't forget to clear the list before leaving
|
||||
list_string_clear(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+28
-2
@@ -14,32 +14,50 @@ RBTREE_DEF(tree_cstr, const char *, M_CSTR_OPLIST)
|
||||
// It is probably the best for beginner in M*LIB to start like this.
|
||||
static void classic1(void)
|
||||
{
|
||||
// Let's declare a tree on the stack.
|
||||
// Even if the tree itself is allocated on the stack,
|
||||
// the nodes will be allocated on the heap.
|
||||
tree_cstr_t tree;
|
||||
|
||||
// Initialize the tree using the provided constructor
|
||||
tree_cstr_init(tree);
|
||||
|
||||
// Let's fill in the tree
|
||||
// Note that the object of the tree are pointer
|
||||
// to array of char. Therefore the strings themselves
|
||||
// are not stored in the tree but only a reference to then
|
||||
// As such, the pointed objects shall not moved nor being
|
||||
// destroyed, which is the case for const C string.
|
||||
tree_cstr_push (tree, "Hello");
|
||||
tree_cstr_push (tree, "World");
|
||||
tree_cstr_push (tree, "How");
|
||||
tree_cstr_push (tree, "Are");
|
||||
tree_cstr_push (tree, "You");
|
||||
|
||||
// Let's print the tree.
|
||||
// We'll use the OUT_STR method to display the tree
|
||||
// without iterating ourself in the tree.
|
||||
printf("\nUsing C string, the generated (sorted) tree is ");
|
||||
tree_cstr_out_str(stdout, tree);
|
||||
printf ("\n");
|
||||
|
||||
// Let's search for the key "How" in the tree.
|
||||
// If it is not found a NULL pointer is returned.
|
||||
// Otherwise a pointer to the key within the tree is returned.
|
||||
// This pointer is valid until a modification operation on the tree is done.
|
||||
const char *present = tree_cstr_get(tree, "How") == NULL ? "not " : "";
|
||||
printf("The word 'How' is %spresent\n", present);
|
||||
|
||||
present = tree_cstr_get(tree, "Not") == NULL ? "not " : "";
|
||||
printf("The word 'Not' is %spresent\n", present);
|
||||
|
||||
// Destroy the tree by calling the destructor.
|
||||
tree_cstr_clear(tree);
|
||||
}
|
||||
|
||||
|
||||
// Let's define another Red Black Tree over the M*LIB strings
|
||||
// Notice that we don't need to specify the oplist for this case.
|
||||
// since the oplist of a string_t is registered globally.
|
||||
RBTREE_DEF(tree_str, string_t)
|
||||
|
||||
// The classic C way
|
||||
@@ -52,16 +70,24 @@ static void classic2(void)
|
||||
|
||||
// STRING_CTE enables to construct a temporary const string_t from a const char *
|
||||
// usable for function call.
|
||||
// Note that this time the full string is stored within the tree,
|
||||
// and not only a pointer to it.
|
||||
tree_str_push (tree, STRING_CTE("Hello"));
|
||||
tree_str_push (tree, STRING_CTE("World"));
|
||||
tree_str_push (tree, STRING_CTE("How"));
|
||||
tree_str_push (tree, STRING_CTE("Are"));
|
||||
tree_str_push (tree, STRING_CTE("You"));
|
||||
// We may also push a const C string into a string_t by calling the emplace function
|
||||
tree_str_emplace (tree, "You");
|
||||
|
||||
// Let's print the tree
|
||||
printf("\nUsing M*LIB string_t, the generated (sorted) tree is ");
|
||||
tree_str_out_str(stdout, tree);
|
||||
printf ("\n");
|
||||
|
||||
// Let's search for the string "How"
|
||||
// We convert it to a temporary string_t, and let's test
|
||||
// if it is found or not by testing if the returned pointer to string_t
|
||||
// is null or not.
|
||||
const char *present = tree_str_get(tree, STRING_CTE("How")) == NULL ? "not " : "";
|
||||
printf("The word 'How' is %spresent\n", present);
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef MY_HEADER
|
||||
#define MY_HEADER
|
||||
|
||||
// Request M*LIB to not inline functions if not the library source
|
||||
#define M_USE_DECL
|
||||
#include "m-string.h"
|
||||
#include "m-array.h"
|
||||
|
||||
ARRAY_DEF(array_str, string_t)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Request M*LIB to define functions
|
||||
// This include both m-string functions and array_str templated functions
|
||||
// Defining M_USE_EXTERN_DEF override M_USE_EXTERN_DECL definition
|
||||
#define M_USE_DEF
|
||||
#include "exm-header.h"
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "exm-header.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
array_str_t a;
|
||||
array_str_init(a);
|
||||
array_str_emplace_back(a, "Hello");
|
||||
array_str_emplace_back(a, "World");
|
||||
printf("a=");
|
||||
array_str_out_str(stdout, a);
|
||||
printf("\n");
|
||||
array_str_clear(a);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef MY_HEADER
|
||||
#define MY_HEADER
|
||||
|
||||
// Request M*LIB to not always inline functions
|
||||
#define M_USE_FINE_GRAINED_LINKAGE
|
||||
#include "m-string.h"
|
||||
#include "m-array.h"
|
||||
|
||||
// The following functions will not be inlined:
|
||||
#define M_USE_DECL
|
||||
ARRAY_DEF(array_str, string_t)
|
||||
#undef M_USE_DECL
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
// Request M*LIB to define functions for functions defined within M_USE_DECL.
|
||||
#define M_USE_DEF
|
||||
#include "exn-header.h"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "exn-header.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
string_t s;
|
||||
string_init_set_str(s, "a=");
|
||||
string_fputs(stdout, s);
|
||||
string_clear(s);
|
||||
array_str_t a;
|
||||
array_str_init(a);
|
||||
array_str_emplace_back(a, "Hello");
|
||||
array_str_emplace_back(a, "World");
|
||||
//printf("a=");
|
||||
array_str_out_str(stdout, a);
|
||||
printf("\n");
|
||||
array_str_clear(a);
|
||||
//main2();
|
||||
return 0;
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "m-core.h"
|
||||
|
||||
/* Define different kind of basic algorithms named 'name' over the container
|
||||
which oplist is 'cont_oplist', as static inline functions.
|
||||
which oplist is 'cont_oplist'.
|
||||
USAGE:
|
||||
ALGO_DEF(algogName, containerOplist|type if oplist has been registered) */
|
||||
#define M_ALGO_DEF(name, cont_oplist) \
|
||||
@@ -189,7 +189,7 @@
|
||||
#define M_ALG0_DEF_SORT(name, container_t, cont_oplist, type_t, type_oplist, it_t, order, sort_name) \
|
||||
\
|
||||
/* Define the encapsulation function that perform the selected order */ \
|
||||
static inline int M_C3(name,sort_name,_cmp)(type_t const*a,type_t const*b) \
|
||||
M_INLINE int M_C3(name,sort_name,_cmp)(type_t const*a,type_t const*b) \
|
||||
{ \
|
||||
return order M_CALL_CMP(type_oplist, *a, *b); \
|
||||
} \
|
||||
@@ -225,7 +225,7 @@
|
||||
#define M_ALG0_DEF_SORT_AUX(name, container_t, cont_oplist, type_t, type_oplist, it_t, sort_name, cmp_func, cmp_param, cmp_arg) \
|
||||
\
|
||||
/* Test if the container is sorted */ \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C3(name,sort_name,_p)(const container_t l cmp_param(name)) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
@@ -253,7 +253,7 @@
|
||||
/* - a selection sort */ \
|
||||
M_IF(M_AND(M_TEST_METHOD_P(SORT, cont_oplist), M_EMPTY_P(cmp_arg)))( \
|
||||
/******** OPTIMIZED SORT FOR CONTAINER *********/ \
|
||||
static inline void M_F(name,sort_name)(container_t l) \
|
||||
M_INLINE void M_F(name,sort_name)(container_t l) \
|
||||
{ \
|
||||
M_CALL_SORT(cont_oplist, l, M_C3(name, sort_name,_cmp)); \
|
||||
} \
|
||||
@@ -265,7 +265,7 @@
|
||||
\
|
||||
/* Split the container 'l' into near even size l1 and l2 * \
|
||||
using odd/even splitting */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name,sort_name,_split)(container_t l1, container_t l2, container_t l) \
|
||||
{ \
|
||||
it_t it; \
|
||||
@@ -280,7 +280,7 @@
|
||||
} \
|
||||
\
|
||||
/* Merge in empty 'l' the sorted container 'l1' and 'l2' */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name,sort_name,_merge)(container_t l, container_t l1, container_t l2 cmp_param(name)) \
|
||||
{ \
|
||||
/* M_ASSERT(M_CALL_EMPTY_P (cont_oplist, l)); */ \
|
||||
@@ -320,7 +320,7 @@
|
||||
} \
|
||||
\
|
||||
/* Sort the container 'l' */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,sort_name)(container_t l cmp_param(name)) \
|
||||
{ \
|
||||
container_t l1; \
|
||||
@@ -363,7 +363,7 @@
|
||||
, \
|
||||
M_IF_METHOD(IT_PREVIOUS, cont_oplist)( \
|
||||
/******** GENERIC INSERTION SORT *********/ \
|
||||
static inline void M_F(name,sort_name)(container_t l cmp_param(name)) \
|
||||
M_INLINE void M_F(name,sort_name)(container_t l cmp_param(name)) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
it_t it2; \
|
||||
@@ -400,7 +400,7 @@
|
||||
\
|
||||
, \
|
||||
/********** GENERIC SELECTION SORT ************/ \
|
||||
static inline void M_F(name,sort_name)(container_t l cmp_param(name)) \
|
||||
M_INLINE void M_F(name,sort_name)(container_t l cmp_param(name)) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
it_t it2; \
|
||||
@@ -433,7 +433,7 @@
|
||||
) /* IF SORT METHOD */ \
|
||||
/* Compute the union of two ***sorted*** containers */ \
|
||||
M_IF_METHOD(IT_INSERT, cont_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name,sort_name,_union)(container_t dst, const container_t src cmp_param(name)) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
@@ -478,7 +478,7 @@
|
||||
\
|
||||
/* Compute the intersection of two ***sorted*** containers */ \
|
||||
M_IF_METHOD(IT_REMOVE, cont_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name,sort_name,_intersect)(container_t dst, const container_t src cmp_param(name)) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
@@ -517,7 +517,7 @@
|
||||
#define M_ALG0_DEF_FIND(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
/* It supposes that the container is not sorted */ \
|
||||
/* Find the next occurrence from it (included) of data */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _find_again) (it_t it, type_t const data) \
|
||||
{ \
|
||||
for ( /*nothing*/ ; !M_CALL_IT_END_P(cont_oplist, it) ; \
|
||||
@@ -528,7 +528,7 @@
|
||||
} \
|
||||
\
|
||||
/* Find the first occurrence of data */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _find) (it_t it, container_t const l, type_t const data) \
|
||||
{ \
|
||||
M_CALL_IT_FIRST(cont_oplist, it, l); \
|
||||
@@ -536,7 +536,7 @@
|
||||
} \
|
||||
\
|
||||
/* Test if data is within the container */ \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _contain_p) (container_t const l, type_t const data) \
|
||||
{ \
|
||||
it_t it; \
|
||||
@@ -549,7 +549,7 @@
|
||||
PREVIOUS & IT_LAST are defined, then search backwards */ \
|
||||
M_IF_METHOD2(PREVIOUS, IT_LAST, cont_oplist) \
|
||||
( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _find_last) (it_t it, container_t const l, type_t const data) \
|
||||
{ \
|
||||
for (M_CALL_IT_LAST(cont_oplist, it, l); \
|
||||
@@ -562,7 +562,7 @@
|
||||
} \
|
||||
, \
|
||||
/* Otherwise search forward, but don't stop on the first occurrence */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _find_last) (it_t it, container_t const l, type_t const data) \
|
||||
{ \
|
||||
M_CALL_IT_END(cont_oplist, it, l); \
|
||||
@@ -578,7 +578,7 @@
|
||||
) /* End of alternative of _find_last */ \
|
||||
\
|
||||
/* Count the number of occurrence of data in the container */ \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _count) (container_t const l, type_t const data) \
|
||||
{ \
|
||||
it_t it; \
|
||||
@@ -594,7 +594,7 @@
|
||||
\
|
||||
\
|
||||
/* Find the next mismatch between the containers */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _mismatch_again) (it_t it1, it_t it2) \
|
||||
{ \
|
||||
for (/* nothing */ ; !M_CALL_IT_END_P(cont_oplist, it1) && \
|
||||
@@ -608,7 +608,7 @@
|
||||
} \
|
||||
\
|
||||
/* Find the first mismatch between the containers */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _mismatch) (it_t it1, it_t it2, container_t const l1, container_t const l2 ) \
|
||||
{ \
|
||||
M_CALL_IT_FIRST(cont_oplist, it1, l1); \
|
||||
@@ -625,7 +625,7 @@
|
||||
#define M_ALG0_DEF_FIND_IF(name, container_t, cont_oplist, type_t, type_oplist, it_t, suffix, test_t, eq_t, call_test, call_eq) \
|
||||
\
|
||||
/* Find the next occurrence that matches the condition */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _find_again_, suffix) (it_t it, test_t func) \
|
||||
{ \
|
||||
for (/*nothing */ ; !M_CALL_IT_END_P(cont_oplist, it) ; \
|
||||
@@ -636,7 +636,7 @@
|
||||
} \
|
||||
\
|
||||
/* Find the first occurrence that matches the condition */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _find_, suffix) (it_t it, container_t l, test_t func) \
|
||||
{ \
|
||||
M_CALL_IT_FIRST(cont_oplist, it, l); \
|
||||
@@ -644,7 +644,7 @@
|
||||
} \
|
||||
\
|
||||
/* Count the number of occurrence that matches the condition */ \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_C3(name, _count_, suffix) (container_t const l, test_t func) \
|
||||
{ \
|
||||
it_t it; \
|
||||
@@ -660,7 +660,7 @@
|
||||
} \
|
||||
\
|
||||
/* Find the next mismatch between the containers according to the condition */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _mismatch_again_, suffix) (it_t it1, it_t it2, eq_t func) \
|
||||
{ \
|
||||
for (/*nothing */ ; !M_CALL_IT_END_P(cont_oplist, it1) && \
|
||||
@@ -674,7 +674,7 @@
|
||||
} \
|
||||
\
|
||||
/* Find the first mismatch between the containers according to the condition */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _mismatch_, suffix) (it_t it1, it_t it2, container_t const l1, \
|
||||
container_t l2, eq_t func) \
|
||||
{ \
|
||||
@@ -688,7 +688,7 @@
|
||||
#define M_ALG0_DEF_FILL(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
\
|
||||
/* Fill all the container with value (overwritten) */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _fill) (container_t l, type_t const value) \
|
||||
{ \
|
||||
for M_EACH(item, l, cont_oplist) { \
|
||||
@@ -698,7 +698,7 @@
|
||||
\
|
||||
/* Fill the container with exactly 'n' occurrence of 'value' */ \
|
||||
M_IF_METHOD(PUSH, cont_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _fill_n) (container_t l, size_t n, type_t const value) \
|
||||
{ \
|
||||
M_CALL_RESET(cont_oplist, l); \
|
||||
@@ -710,7 +710,7 @@
|
||||
\
|
||||
/* Fill the container with FOR('value'; 'value'+'inc') */ \
|
||||
M_IF_METHOD(ADD, type_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _fill_a) (container_t l, type_t const value, type_t const inc) \
|
||||
{ \
|
||||
type_t tmp; \
|
||||
@@ -724,7 +724,7 @@
|
||||
\
|
||||
/* Fill the container with n occurences of FOR('value'; 'value'+'inc') */ \
|
||||
M_IF_METHOD(PUSH, cont_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _fill_an) (container_t l, size_t n, type_t const value, type_t const inc) \
|
||||
{ \
|
||||
type_t tmp; \
|
||||
@@ -744,7 +744,7 @@
|
||||
#define M_ALG0_DEF_MAP(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
\
|
||||
/* Apply func for all elements of the container */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _for_each) (container_t l, M_F(name, _apply_cb_ct) func) \
|
||||
{ \
|
||||
for M_EACH(item, l, cont_oplist) { \
|
||||
@@ -756,7 +756,7 @@
|
||||
M_IF_METHOD(PUSH_MOVE, cont_oplist)( \
|
||||
\
|
||||
/* Apply func for all elements of the container src and push the result in dst */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _transform) (container_t dst, \
|
||||
container_t src, \
|
||||
M_F(name, _transform_cb_ct) func) \
|
||||
@@ -775,7 +775,7 @@
|
||||
\
|
||||
/* Reduce all elements of the container in dst in function of func */ \
|
||||
M_IF_METHOD(SET, type_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reduce) (type_t *dest, container_t const l, \
|
||||
M_F(name, _transform_cb_ct) func) \
|
||||
{ \
|
||||
@@ -793,7 +793,7 @@
|
||||
\
|
||||
/* Reduce all transformed elements of the container in dst in function of func */ \
|
||||
M_IF_METHOD(INIT, type_oplist)( \
|
||||
static inline \
|
||||
M_INLINE \
|
||||
void M_F(name, _map_reduce) (type_t *dest, \
|
||||
const container_t l, \
|
||||
M_F(name, _transform_cb_ct) redFunc, \
|
||||
@@ -819,7 +819,7 @@
|
||||
/* Define ALL_OF algorithms */
|
||||
#define M_ALG0_DEF_ALL_OF(name, container_t, cont_oplist, type_t, type_oplist, it_t, suffix, func_t, call) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C4(name, _any_of, suffix, p) (container_t const l, \
|
||||
func_t func ) \
|
||||
{ \
|
||||
@@ -830,7 +830,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C4(name, _all_of, suffix, p) (container_t const l, \
|
||||
func_t func ) \
|
||||
{ \
|
||||
@@ -841,7 +841,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C4(name, _none_of, suffix, p) (container_t l, \
|
||||
func_t func ) \
|
||||
{ \
|
||||
@@ -856,7 +856,7 @@
|
||||
/* Define MIN / MAX algorithms */
|
||||
#define M_ALG0_DEF_MINMAX(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
\
|
||||
static inline type_t * \
|
||||
M_INLINE type_t * \
|
||||
M_F(name, _min) (const container_t l) \
|
||||
{ \
|
||||
type_t *min = NULL; \
|
||||
@@ -869,7 +869,7 @@
|
||||
return min; \
|
||||
} \
|
||||
\
|
||||
static inline type_t * \
|
||||
M_INLINE type_t * \
|
||||
M_F(name, _max) (const container_t l) \
|
||||
{ \
|
||||
type_t *max = NULL; \
|
||||
@@ -882,7 +882,7 @@
|
||||
return max; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _minmax) (type_t **min_p, type_t **max_p, \
|
||||
const container_t l) \
|
||||
{ \
|
||||
@@ -905,7 +905,7 @@
|
||||
/* Define functions based on remove method */
|
||||
#define M_ALG0_DEF_REMOVE(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _uniq)(container_t l) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
@@ -927,7 +927,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove_val)(container_t l, type_t const val) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
@@ -942,7 +942,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove_if)(container_t l, M_F(name, _test_cb_ct) func) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
@@ -961,7 +961,7 @@
|
||||
#define M_ALG0_DEF_VECTOR(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
|
||||
\
|
||||
M_IF_METHOD(ADD, type_oplist)( \
|
||||
static inline void M_F(name, _add) (container_t dst, const container_t src) \
|
||||
M_INLINE void M_F(name, _add) (container_t dst, const container_t src) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
it_t itDst; \
|
||||
@@ -979,7 +979,7 @@
|
||||
, /* NO_ADD METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD(SUB, type_oplist)( \
|
||||
static inline void M_F(name, _sub) (container_t dst, const container_t src) \
|
||||
M_INLINE void M_F(name, _sub) (container_t dst, const container_t src) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
it_t itDst; \
|
||||
@@ -997,7 +997,7 @@
|
||||
, /* NO_SUB METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD(MUL, type_oplist)( \
|
||||
static inline void M_F(name, _mul) (container_t dst, const container_t src) \
|
||||
M_INLINE void M_F(name, _mul) (container_t dst, const container_t src) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
it_t itDst; \
|
||||
@@ -1015,7 +1015,7 @@
|
||||
, /* NO_MUL METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD(DIV, type_oplist)( \
|
||||
static inline void M_F(name, _div) (container_t dst, const container_t src) \
|
||||
M_INLINE void M_F(name, _div) (container_t dst, const container_t src) \
|
||||
{ \
|
||||
it_t itSrc; \
|
||||
it_t itDst; \
|
||||
|
||||
@@ -131,9 +131,6 @@
|
||||
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
||||
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
|
||||
,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -204,7 +201,7 @@
|
||||
/* Define the core functions */
|
||||
#define M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(array_t v) \
|
||||
{ \
|
||||
M_ASSERT (v != NULL); \
|
||||
@@ -215,7 +212,7 @@
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -225,7 +222,7 @@
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -237,7 +234,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD2(INIT_SET, SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(array_t d, const array_t s) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(d); \
|
||||
@@ -265,7 +262,7 @@
|
||||
M_ARRA4_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(array_t d, const array_t s) \
|
||||
{ \
|
||||
M_ASSERT (d != s); \
|
||||
@@ -274,7 +271,7 @@
|
||||
} \
|
||||
, /* No SET & INIT_SET */) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(array_t d, array_t s) \
|
||||
{ \
|
||||
M_ASSERT (d != s); \
|
||||
@@ -288,7 +285,7 @@
|
||||
M_ARRA4_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(array_t d, array_t s) \
|
||||
{ \
|
||||
M_ASSERT (d != s); \
|
||||
@@ -297,7 +294,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set_at)(array_t v, size_t i, type const x) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -307,7 +304,7 @@
|
||||
} \
|
||||
, /* No SET */) \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _back)(array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -316,7 +313,7 @@
|
||||
return &v->ptr[v->size-1]; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_raw)(array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -345,7 +342,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT_SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_back)(array_t v, type const x) \
|
||||
{ \
|
||||
type *data = M_F(name, _push_raw)(v); \
|
||||
@@ -356,7 +353,7 @@
|
||||
, /* No INIT_SET */ ) \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_new)(array_t v) \
|
||||
{ \
|
||||
type *data = M_F(name, _push_raw)(v); \
|
||||
@@ -368,7 +365,7 @@
|
||||
, /* No INIT */ ) \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_move)(array_t v, type *x) \
|
||||
{ \
|
||||
M_ASSERT (x != NULL); \
|
||||
@@ -380,7 +377,7 @@
|
||||
, /* INIT_SET | INIT_MOVE */ ) \
|
||||
\
|
||||
M_IF_METHOD(INIT_SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_at)(array_t v, size_t key, type const x) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -410,7 +407,7 @@
|
||||
, /* No INIT_SET */ ) \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _resize)(array_t v, size_t size) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -439,7 +436,7 @@
|
||||
} \
|
||||
, /* No INIT */ ) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reserve)(array_t v, size_t alloc) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -464,7 +461,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _safe_get)(array_t v, size_t idx) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -498,7 +495,7 @@
|
||||
, /* No INIT */) \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_back)(type *dest, array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -515,7 +512,7 @@
|
||||
, /* SET | INIT_MOVE */ ) \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(INIT_SET, INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_move)(type *dest, array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -529,7 +526,7 @@
|
||||
, /* INIT_SET | INIT_MOVE */ ) \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_until)(array_t v, it_t pos) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -539,21 +536,21 @@
|
||||
} \
|
||||
, /* No INIT */ ) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
return v->size == 0; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
return v->size; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -561,7 +558,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_at)(type *dest, array_t v, size_t i) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -576,7 +573,7 @@
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _erase)(array_t a, size_t i) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(a); \
|
||||
@@ -587,7 +584,7 @@
|
||||
, /* SET | INIT_MOVE */ ) \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _insert_v)(array_t v, size_t i, size_t num) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -623,7 +620,7 @@
|
||||
} \
|
||||
, /* No INIT */) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove_v)(array_t v, size_t i, size_t j) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -637,7 +634,7 @@
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(array_t v1, array_t v2) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v1); \
|
||||
@@ -650,7 +647,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist) ( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap_at)(array_t v, size_t i, size_t j) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -665,7 +662,7 @@
|
||||
} \
|
||||
, /* INIT_SET | INIT_MOVE */ ) \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _get)(const array_t v, size_t i) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -674,7 +671,7 @@
|
||||
return &v->ptr[i]; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cget)(const array_t v, size_t i) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -683,7 +680,7 @@
|
||||
return M_CONST_CAST(type, &v->ptr[i]); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _front)(const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -691,7 +688,7 @@
|
||||
return M_F(name, _get)(v, 0); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -700,7 +697,7 @@
|
||||
it->array = v; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(it_t it, const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -710,7 +707,7 @@
|
||||
it->array = v; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, const array_t v) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(v); \
|
||||
@@ -719,7 +716,7 @@
|
||||
it->array = v; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t it, const it_t org) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && org != NULL); \
|
||||
@@ -728,14 +725,14 @@
|
||||
M_ARRA4_CONTRACT(it->array); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL && it->array != NULL); \
|
||||
return it->index >= it->array->size; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL && it->array != NULL); \
|
||||
@@ -744,7 +741,7 @@
|
||||
return it->index + 1 >= it->array->size; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const it_t it1, \
|
||||
const it_t it2) \
|
||||
{ \
|
||||
@@ -752,14 +749,14 @@
|
||||
return it1->array == it2->array && it1->index == it2->index; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL && it->array != NULL); \
|
||||
it->index ++; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL && it->array != NULL); \
|
||||
@@ -768,14 +765,14 @@
|
||||
it->index --; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
return M_F(name, _get)(it->array, it->index); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
@@ -783,7 +780,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT_SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _insert)(array_t a, it_t it, type const x) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && a == it->array); \
|
||||
@@ -794,7 +791,7 @@
|
||||
, /* End of INIT_SET */ ) \
|
||||
\
|
||||
M_IF_AT_LEAST_METHOD(SET, INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove)(array_t a, it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && a == it->array); \
|
||||
@@ -805,7 +802,7 @@
|
||||
\
|
||||
M_IF_METHOD(CMP, oplist) \
|
||||
( \
|
||||
static inline void M_F(name, _special_sort)(array_t l, \
|
||||
M_INLINE void M_F(name, _special_sort)(array_t l, \
|
||||
int (*func_type) (type const *a, type const *b)) \
|
||||
{ \
|
||||
/* Using qsort is more compact but slower than a full templated \
|
||||
@@ -817,7 +814,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD2(SWAP, SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_arra4_,name,_stable_sort_noalloc)(type tab[], size_t size, type tmp[]) \
|
||||
{ \
|
||||
size_t th = 4; \
|
||||
@@ -888,7 +885,7 @@
|
||||
M_ASSERT (org_tab == tab); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _special_stable_sort)(array_t l) \
|
||||
{ \
|
||||
if (M_UNLIKELY (l->size < 2)) \
|
||||
@@ -907,7 +904,7 @@
|
||||
,) /* IF CMP oplist */ \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(const array_t array1, \
|
||||
const array_t array2) \
|
||||
{ \
|
||||
@@ -926,7 +923,7 @@
|
||||
, /* no EQUAL */ ) \
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _hash)(const array_t array) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
@@ -939,7 +936,7 @@
|
||||
} \
|
||||
, /* no HASH */ ) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice)(array_t a1, array_t a2) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(a1); \
|
||||
@@ -972,7 +969,7 @@
|
||||
#define M_ARRA4_DEF_IO(name, type, oplist, array_t, it_t) \
|
||||
\
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(m_string_t str, array_t const array, \
|
||||
bool append) \
|
||||
{ \
|
||||
@@ -992,7 +989,7 @@
|
||||
, /* no GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, const array_t array) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
@@ -1009,39 +1006,35 @@
|
||||
, /* no OUT_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD2(PARSE_STR, INIT, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(array_t array, const char str[], const char**endp) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
M_ASSERT (str != NULL); \
|
||||
M_F(name,_reset)(array); \
|
||||
bool success = false; \
|
||||
int c = *str++; \
|
||||
if (M_UNLIKELY (c != '[')) goto exit; \
|
||||
c = *str++; \
|
||||
if (M_UNLIKELY (c == ']')) { success = true; goto exit; } \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
if (M_UNLIKELY (c != '[')) { c = 0; goto exit; } \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (M_UNLIKELY (c == ']')) { goto exit; } \
|
||||
if (M_UNLIKELY (c == 0)) { goto exit; } \
|
||||
str--; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c == 0) { goto exit_clear; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
success = (c == ']'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c == 0) { c = 0; break; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
exit: \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no PARSE_STR & INIT */ ) \
|
||||
\
|
||||
M_IF_METHOD2(IN_STR, INIT, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(array_t array, FILE *file) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
@@ -1053,22 +1046,21 @@
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) { break; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false || c == EOF) { c = 0; break; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no IN_STR & INIT */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, const array_t array) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
@@ -1089,7 +1081,7 @@
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
\
|
||||
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(array_t array, m_serial_read_t f) \
|
||||
{ \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
@@ -1102,19 +1094,15 @@
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) { \
|
||||
return ret; \
|
||||
} \
|
||||
if (estimated_size != 0) { \
|
||||
/* The format has given an estimation of the array size */ \
|
||||
M_F(name, _reserve)(array, estimated_size); \
|
||||
M_F(name, _reserve)(array, estimated_size); \
|
||||
M_QLET(item, type, oplist) { \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
} \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(array, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_ARRA4_CONTRACT(array); \
|
||||
return ret; \
|
||||
} \
|
||||
@@ -1122,7 +1110,7 @@
|
||||
|
||||
/* Definition of the emplace_back function for arrays */
|
||||
#define M_ARRA4_EMPLACE_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
|
||||
+1
-1
@@ -226,7 +226,7 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
||||
#endif
|
||||
|
||||
/* (INTERNAL) Unlock the mutex and return the given value */
|
||||
static inline long long atomic_fetch_unlock (m_mutex_t *lock, long long val)
|
||||
M_INLINE long long atomic_fetch_unlock (m_mutex_t *lock, long long val)
|
||||
{
|
||||
m_mutex_unlock (*lock);
|
||||
return val;
|
||||
|
||||
+51
-51
@@ -81,7 +81,7 @@ typedef struct m_bitset_it_s {
|
||||
} m_bitset_it_t[1];
|
||||
|
||||
/* Initialize a bitset (CONSTRUCTOR) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_init(m_bitset_t t)
|
||||
{
|
||||
M_ASSERT (t != NULL);
|
||||
@@ -93,7 +93,7 @@ m_bitset_init(m_bitset_t t)
|
||||
}
|
||||
|
||||
/* Clean a bitset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_reset(m_bitset_t t)
|
||||
{
|
||||
M_B1TSET_CONTRACT(t);
|
||||
@@ -101,7 +101,7 @@ m_bitset_reset(m_bitset_t t)
|
||||
}
|
||||
|
||||
/* Clear a bitset (DESTRUCTOR) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_clear(m_bitset_t t)
|
||||
{
|
||||
m_bitset_reset(t);
|
||||
@@ -114,7 +114,7 @@ m_bitset_clear(m_bitset_t t)
|
||||
}
|
||||
|
||||
/* Set a bitset to another one */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_set(m_bitset_t d, const m_bitset_t s)
|
||||
{
|
||||
M_B1TSET_CONTRACT(d);
|
||||
@@ -141,7 +141,7 @@ m_bitset_set(m_bitset_t d, const m_bitset_t s)
|
||||
}
|
||||
|
||||
/* Initialize & set a bitset to another one (CONSTRUCTOR) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_init_set(m_bitset_t d, const m_bitset_t s)
|
||||
{
|
||||
M_ASSERT (d != s);
|
||||
@@ -150,7 +150,7 @@ m_bitset_init_set(m_bitset_t d, const m_bitset_t s)
|
||||
}
|
||||
|
||||
/* Initialize & move a bitset (CONSTRUCTOR) from another one (DESTRUCTOR) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_init_move(m_bitset_t d, m_bitset_t s)
|
||||
{
|
||||
M_B1TSET_CONTRACT(s);
|
||||
@@ -164,7 +164,7 @@ m_bitset_init_move(m_bitset_t d, m_bitset_t s)
|
||||
}
|
||||
|
||||
/* Move a bitset from another one (DESTRUCTOR) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_move(m_bitset_t d, m_bitset_t s)
|
||||
{
|
||||
m_bitset_clear(d);
|
||||
@@ -172,7 +172,7 @@ m_bitset_move(m_bitset_t d, m_bitset_t s)
|
||||
}
|
||||
|
||||
/* Set the bit 'i' in the bitset to the value 'x' */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_set_at(m_bitset_t v, size_t i, bool x)
|
||||
{
|
||||
M_B1TSET_CONTRACT(v);
|
||||
@@ -187,7 +187,7 @@ m_bitset_set_at(m_bitset_t v, size_t i, bool x)
|
||||
}
|
||||
|
||||
/* Flip the bit 'i' in the bitset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_flip_at(m_bitset_t v, size_t i)
|
||||
{
|
||||
M_B1TSET_CONTRACT(v);
|
||||
@@ -200,7 +200,7 @@ m_bitset_flip_at(m_bitset_t v, size_t i)
|
||||
}
|
||||
|
||||
/* Push back the boolean 'x' in the bitset (increasing the bitset) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_push_back (m_bitset_t v, bool x)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -239,7 +239,7 @@ m_bitset_push_back (m_bitset_t v, bool x)
|
||||
}
|
||||
|
||||
/* Resize the bitset to have exactly 'size' bits */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_resize (m_bitset_t v, size_t size)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -287,7 +287,7 @@ m_bitset_resize (m_bitset_t v, size_t size)
|
||||
}
|
||||
|
||||
/* Reserve allocation in the bitset to accomodate at least 'size' bits without reallocation */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_reserve (m_bitset_t v, size_t alloc)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -319,7 +319,7 @@ m_bitset_reserve (m_bitset_t v, size_t alloc)
|
||||
* NOTE: Interface is a little bit different:
|
||||
* It doesn't return a pointer to the data, but the data itself.
|
||||
*/
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_get(const m_bitset_t v, size_t i)
|
||||
{
|
||||
M_B1TSET_CONTRACT(v);
|
||||
@@ -334,7 +334,7 @@ m_bitset_get(const m_bitset_t v, size_t i)
|
||||
#define m_bitset_cget m_bitset_get
|
||||
|
||||
/* Pop back the last bit in the bitset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_pop_back(bool *dest, m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -354,7 +354,7 @@ m_bitset_pop_back(bool *dest, m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Return the front bit value in the bitset */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_front(m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -363,7 +363,7 @@ m_bitset_front(m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Return the back bit value in the bitset */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_back(m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -372,7 +372,7 @@ m_bitset_back(m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Test if the bitset is empty (no bits stored)*/
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_empty_p(m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -380,7 +380,7 @@ m_bitset_empty_p(m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Return the number of bits of the bitset */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_size(m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -388,7 +388,7 @@ m_bitset_size(m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Return the capacity in limbs of the bitset */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_capacity(m_bitset_t v)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v);
|
||||
@@ -396,7 +396,7 @@ m_bitset_capacity(m_bitset_t v)
|
||||
}
|
||||
|
||||
/* Swap the bit at index i and j of the bitset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_swap_at (m_bitset_t v, size_t i, size_t j)
|
||||
{
|
||||
M_ASSERT_INDEX(i, v->size);
|
||||
@@ -409,7 +409,7 @@ m_bitset_swap_at (m_bitset_t v, size_t i, size_t j)
|
||||
}
|
||||
|
||||
/* Swap the bitsets */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_swap (m_bitset_t v1, m_bitset_t v2)
|
||||
{
|
||||
M_B1TSET_CONTRACT (v1);
|
||||
@@ -425,7 +425,7 @@ m_bitset_swap (m_bitset_t v1, m_bitset_t v2)
|
||||
* integrating the carry in the lowest position.
|
||||
* Return the new carry.
|
||||
*/
|
||||
static inline m_b1tset_limb_ct
|
||||
M_INLINE m_b1tset_limb_ct
|
||||
m_b1tset_lshift(m_b1tset_limb_ct ptr[], size_t n, m_b1tset_limb_ct carry)
|
||||
{
|
||||
for(size_t i = 0; i < n; i++) {
|
||||
@@ -440,7 +440,7 @@ m_b1tset_lshift(m_b1tset_limb_ct ptr[], size_t n, m_b1tset_limb_ct carry)
|
||||
* integrating the carry in the lowest position.
|
||||
* Return the new carry.
|
||||
*/
|
||||
static inline m_b1tset_limb_ct
|
||||
M_INLINE m_b1tset_limb_ct
|
||||
m_b1tset_rshift(m_b1tset_limb_ct ptr[], size_t n, m_b1tset_limb_ct carry)
|
||||
{
|
||||
for(size_t i = n - 1; i < n; i--) {
|
||||
@@ -453,7 +453,7 @@ m_b1tset_rshift(m_b1tset_limb_ct ptr[], size_t n, m_b1tset_limb_ct carry)
|
||||
|
||||
/* Insert a new bit at position 'key' of value 'value' in the bitset 'set'
|
||||
shifting the set accordingly */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_push_at(m_bitset_t set, size_t key, bool value)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -481,7 +481,7 @@ m_bitset_push_at(m_bitset_t set, size_t key, bool value)
|
||||
|
||||
/* Pop a new bit at position 'key' in the bitset
|
||||
* and return in *dest its value if *dest exists */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_pop_at(bool *dest, m_bitset_t set, size_t key)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -507,7 +507,7 @@ m_bitset_pop_at(bool *dest, m_bitset_t set, size_t key)
|
||||
}
|
||||
|
||||
/* Test if two bitsets are equal */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_equal_p (const m_bitset_t set1, const m_bitset_t set2)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set1);
|
||||
@@ -524,7 +524,7 @@ m_bitset_equal_p (const m_bitset_t set1, const m_bitset_t set2)
|
||||
}
|
||||
|
||||
/* Initialize an iterator to the first bit of the biset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_it(m_bitset_it_t it, m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -533,7 +533,7 @@ m_bitset_it(m_bitset_it_t it, m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Initialize an iterator to reference the same bit as the given one*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_it_set(m_bitset_it_t it, const m_bitset_it_t itorg)
|
||||
{
|
||||
M_ASSERT (it != NULL && itorg != NULL);
|
||||
@@ -542,7 +542,7 @@ m_bitset_it_set(m_bitset_it_t it, const m_bitset_it_t itorg)
|
||||
}
|
||||
|
||||
/* Initialize an iterator to reference the last bit of the bitset*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_it_last(m_bitset_it_t it, m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -551,7 +551,7 @@ m_bitset_it_last(m_bitset_it_t it, m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Initialize an iterator to reference no valid bit of the bitset*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_it_end(m_bitset_it_t it, m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -560,7 +560,7 @@ m_bitset_it_end(m_bitset_it_t it, m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Test if an iterator references no valid bit of the bitset anymore */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_end_p(const m_bitset_it_t it)
|
||||
{
|
||||
M_ASSERT (it != NULL && it->set != NULL);
|
||||
@@ -568,7 +568,7 @@ m_bitset_end_p(const m_bitset_it_t it)
|
||||
}
|
||||
|
||||
/* Test if an iterator references the last (or end) bit of the bitset anymore */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_last_p(const m_bitset_it_t it)
|
||||
{
|
||||
M_ASSERT (it != NULL && it->set != NULL);
|
||||
@@ -578,7 +578,7 @@ m_bitset_last_p(const m_bitset_it_t it)
|
||||
}
|
||||
|
||||
/* Test if both iterators reference the same bit */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_it_equal_p(const m_bitset_it_t it1, const m_bitset_it_t it2)
|
||||
{
|
||||
M_ASSERT (it1 != NULL && it2 != NULL);
|
||||
@@ -586,7 +586,7 @@ m_bitset_it_equal_p(const m_bitset_it_t it1, const m_bitset_it_t it2)
|
||||
}
|
||||
|
||||
/* Move the iterator to the next bit */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_next(m_bitset_it_t it)
|
||||
{
|
||||
M_ASSERT (it != NULL && it->set != NULL);
|
||||
@@ -594,7 +594,7 @@ m_bitset_next(m_bitset_it_t it)
|
||||
}
|
||||
|
||||
/* Move the iterator to the previous bit */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_previous(m_bitset_it_t it)
|
||||
{
|
||||
M_ASSERT (it != NULL && it->set != NULL);
|
||||
@@ -605,7 +605,7 @@ m_bitset_previous(m_bitset_it_t it)
|
||||
|
||||
/* Return a pointer to the bit referenced by the iterator
|
||||
* Only one reference is possible at a time per iterator */
|
||||
static inline const bool *
|
||||
M_INLINE const bool *
|
||||
m_bitset_cref(m_bitset_it_t it)
|
||||
{
|
||||
M_ASSERT (it != NULL && it->set != NULL);
|
||||
@@ -614,7 +614,7 @@ m_bitset_cref(m_bitset_it_t it)
|
||||
}
|
||||
|
||||
/* Output the bitset as a formatted text in a FILE */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_out_str(FILE *file, const m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -629,7 +629,7 @@ m_bitset_out_str(FILE *file, const m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Input the bitset from a formatted text in a FILE */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_in_str(m_bitset_t set, FILE *file)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -648,7 +648,7 @@ m_bitset_in_str(m_bitset_t set, FILE *file)
|
||||
}
|
||||
|
||||
/* Parse the bitset from a formatted text in a C string */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_parse_str(m_bitset_t set, const char str[], const char **endptr)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
@@ -672,7 +672,7 @@ m_bitset_parse_str(m_bitset_t set, const char str[], const char **endptr)
|
||||
}
|
||||
|
||||
/* Set the bitset from a formatted text in a C string */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_bitset_set_str(m_bitset_t dest, const char str[])
|
||||
{
|
||||
return m_bitset_parse_str(dest, str, NULL);
|
||||
@@ -680,7 +680,7 @@ m_bitset_set_str(m_bitset_t dest, const char str[])
|
||||
|
||||
/* Perform an AND operation between the bitsets,
|
||||
* up to the minimum size of both bitsets */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_and(m_bitset_t dest, const m_bitset_t src)
|
||||
{
|
||||
M_B1TSET_CONTRACT(dest);
|
||||
@@ -696,7 +696,7 @@ m_bitset_and(m_bitset_t dest, const m_bitset_t src)
|
||||
|
||||
/* Perform an OR operation between the bitsets,
|
||||
* up to the minimum size of both bitsets */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_or(m_bitset_t dest, const m_bitset_t src)
|
||||
{
|
||||
M_B1TSET_CONTRACT(dest);
|
||||
@@ -712,7 +712,7 @@ m_bitset_or(m_bitset_t dest, const m_bitset_t src)
|
||||
|
||||
/* Perform an XOR operation between the bitsets,
|
||||
* up to the minimum size of both bitsets */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_xor(m_bitset_t dest, const m_bitset_t src)
|
||||
{
|
||||
M_B1TSET_CONTRACT(dest);
|
||||
@@ -733,7 +733,7 @@ m_bitset_xor(m_bitset_t dest, const m_bitset_t src)
|
||||
}
|
||||
|
||||
/* Perform a NOT operation of the bitset */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_not(m_bitset_t dest)
|
||||
{
|
||||
M_B1TSET_CONTRACT(dest);
|
||||
@@ -751,7 +751,7 @@ m_bitset_not(m_bitset_t dest)
|
||||
}
|
||||
|
||||
/* Copute a hash of the bitset */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_hash(const m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT(set);
|
||||
@@ -764,7 +764,7 @@ m_bitset_hash(const m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Count the number of leading zero */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_clz(const m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT(set);
|
||||
@@ -792,7 +792,7 @@ m_bitset_clz(const m_bitset_t set)
|
||||
}
|
||||
|
||||
/* Count the number of trailing zero */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_ctz(const m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT(set);
|
||||
@@ -819,14 +819,14 @@ m_bitset_ctz(const m_bitset_t set)
|
||||
|
||||
// For GCC or CLANG or ICC
|
||||
#if defined(__GNUC__)
|
||||
static inline size_t m_b1tset_popcount64(m_b1tset_limb_ct limb)
|
||||
M_INLINE size_t m_b1tset_popcount64(m_b1tset_limb_ct limb)
|
||||
{
|
||||
return (size_t) __builtin_popcountll(limb);
|
||||
}
|
||||
#else
|
||||
// MSVC __popcnt64 may not exist on the target architecture (no emulation layer)
|
||||
// Use emulation layer: https://en.wikipedia.org/wiki/Hamming_weight
|
||||
static inline size_t m_b1tset_popcount64(m_b1tset_limb_ct limb)
|
||||
M_INLINE size_t m_b1tset_popcount64(m_b1tset_limb_ct limb)
|
||||
{
|
||||
limb = limb - ((limb >> 1) & 0x5555555555555555ULL);
|
||||
limb = (limb & 0x3333333333333333ULL) + ((limb >> 2) & 0x3333333333333333ULL);
|
||||
@@ -836,7 +836,7 @@ static inline size_t m_b1tset_popcount64(m_b1tset_limb_ct limb)
|
||||
#endif
|
||||
|
||||
/* Count the number of 1 */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_bitset_popcount(const m_bitset_t set)
|
||||
{
|
||||
M_B1TSET_CONTRACT(set);
|
||||
@@ -962,7 +962,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
|
||||
/* Output to a m_string_t 'str' the formatted text representation of the bitset 'set'
|
||||
or append it to the strinf (append=true) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_bitset_get_str(m_string_t str, const m_bitset_t set, bool append)
|
||||
{
|
||||
M_B1TSET_CONTRACT (set);
|
||||
|
||||
+51
-57
@@ -188,9 +188,6 @@
|
||||
M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),), \
|
||||
M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),), \
|
||||
M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -247,9 +244,6 @@
|
||||
M_IF_METHOD_BOTH(IN_SERIAL, key_oplist, value_oplist)(IN_SERIAL(M_F(name, _in_serial)),), \
|
||||
M_IF_METHOD_BOTH(EQUAL, key_oplist, value_oplist)(EQUAL(M_F(name, _equal_p)),), \
|
||||
M_IF_METHOD_BOTH(HASH, key_oplist, value_oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, key_oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, key_oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, key_oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -412,7 +406,7 @@
|
||||
\
|
||||
/* Allocate a new node */ \
|
||||
/* TODO: Can be specialized to alloc for leaf or for non leaf */ \
|
||||
static inline node_t M_F(name, _new_node)(void) \
|
||||
M_INLINE node_t M_F(name, _new_node)(void) \
|
||||
{ \
|
||||
M_STATIC_ASSERT(N >= 2, M_LIB_ILLEGAL_PARAM, \
|
||||
"Number of items per node shall be >= 2."); \
|
||||
@@ -426,14 +420,14 @@
|
||||
return n; \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _init)(tree_t b) \
|
||||
M_INLINE void M_F(name, _init)(tree_t b) \
|
||||
{ \
|
||||
b->root = M_F(name, _new_node)(); \
|
||||
b->size = 0; \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline bool M_F(name, _is_leaf)(const node_t n) \
|
||||
M_INLINE bool M_F(name, _is_leaf)(const node_t n) \
|
||||
{ \
|
||||
/* We consider the empty node as a leaf */ \
|
||||
/* Only the root node can be empty */ \
|
||||
@@ -441,7 +435,7 @@
|
||||
} \
|
||||
\
|
||||
/* Return the number of keys of the node */ \
|
||||
static inline int M_F(name, _get_num)(const node_t n) \
|
||||
M_INLINE int M_F(name, _get_num)(const node_t n) \
|
||||
{ \
|
||||
int num = n->num; \
|
||||
num = num < 0 ? -num : num; \
|
||||
@@ -449,7 +443,7 @@
|
||||
return num; \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _reset)(tree_t b) \
|
||||
M_INLINE void M_F(name, _reset)(tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
node_t next, n = b->root; \
|
||||
@@ -492,7 +486,7 @@
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _clear)(tree_t b) \
|
||||
M_INLINE void M_F(name, _clear)(tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
M_F(name, _reset)(b); \
|
||||
@@ -502,7 +496,7 @@
|
||||
} \
|
||||
\
|
||||
/* Copy recursively the node 'o' of root node 'root' */ \
|
||||
static inline node_t M_F(name, _copy_node)(const node_t o, const node_t root) \
|
||||
M_INLINE node_t M_F(name, _copy_node)(const node_t o, const node_t root) \
|
||||
{ \
|
||||
node_t n = M_F(name, _new_node)(); \
|
||||
/* Set default number of keys and type to copy */ \
|
||||
@@ -548,7 +542,7 @@
|
||||
return n; \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _init_set)(tree_t b, const tree_t o) \
|
||||
M_INLINE void M_F(name, _init_set)(tree_t b, const tree_t o) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, o); \
|
||||
M_ASSERT (b != NULL); \
|
||||
@@ -558,7 +552,7 @@
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _set)(tree_t b, const tree_t o) \
|
||||
M_INLINE void M_F(name, _set)(tree_t b, const tree_t o) \
|
||||
{ \
|
||||
/* NOTE: We could reuse the already allocated nodes of 'b'. \
|
||||
Not sure if it worth the effort */ \
|
||||
@@ -566,20 +560,20 @@
|
||||
M_F(name, _init_set)(b, o); \
|
||||
} \
|
||||
\
|
||||
static inline bool M_F(name, _empty_p)(const tree_t b) \
|
||||
M_INLINE bool M_F(name, _empty_p)(const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
/* root shall be an empty leaf */ \
|
||||
return b->size == 0; \
|
||||
} \
|
||||
\
|
||||
static inline size_t M_F(name, _size)(const tree_t b) \
|
||||
M_INLINE size_t M_F(name, _size)(const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
return b->size; \
|
||||
} \
|
||||
\
|
||||
static inline node_t M_F(name, _search_for_leaf)(pit_t pit, const tree_t b, key_t const key) \
|
||||
M_INLINE node_t M_F(name, _search_for_leaf)(pit_t pit, const tree_t b, key_t const key) \
|
||||
{ \
|
||||
node_t n = b->root; \
|
||||
int np = 0; \
|
||||
@@ -608,7 +602,7 @@
|
||||
return n; \
|
||||
} \
|
||||
\
|
||||
static inline value_t *M_F(name, _get)(const tree_t b, key_t const key) \
|
||||
M_INLINE value_t *M_F(name, _get)(const tree_t b, key_t const key) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
pit_t pit; \
|
||||
@@ -628,12 +622,12 @@
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static inline value_t const *M_F(name, _cget)(const tree_t b, key_t const key) \
|
||||
M_INLINE value_t const *M_F(name, _cget)(const tree_t b, key_t const key) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_F(name, _get)(b, key)); \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
M_INLINE int \
|
||||
M_F(name, _search_and_insert_in_leaf)(node_t n, key_t const key \
|
||||
M_IF(isMap)( M_DEFERRED_COMMA value_t const value,) ) \
|
||||
{ \
|
||||
@@ -665,7 +659,7 @@
|
||||
return i; \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
M_INLINE int \
|
||||
M_F(name, _search_and_insert_in_node)(node_t n, node_t l, key_t key) \
|
||||
{ \
|
||||
M_ASSERT (!M_F(name, _is_leaf)(n)); \
|
||||
@@ -688,7 +682,7 @@
|
||||
return i; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_IF(isMap)(M_F(name, _set_at),M_F(name,_push))(tree_t b, key_t const key \
|
||||
M_IF(isMap)(M_DEFERRED_COMMA value_t const value,)) \
|
||||
{ \
|
||||
@@ -778,7 +772,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline value_t *M_F(name, _safe_get)(tree_t b, key_t const key) \
|
||||
M_INLINE value_t *M_F(name, _safe_get)(tree_t b, key_t const key) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
/* Not optimized implementation */ \
|
||||
@@ -797,7 +791,7 @@
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
M_INLINE int \
|
||||
M_F(name, _search_and_remove_in_leaf)(node_t n, key_t const key) \
|
||||
{ \
|
||||
M_ASSERT(M_F(name, _is_leaf)(n)); \
|
||||
@@ -817,7 +811,7 @@
|
||||
return -1; /* Not found */ \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _left_shift)(node_t parent, int k) \
|
||||
M_INLINE void M_F(name, _left_shift)(node_t parent, int k) \
|
||||
{ \
|
||||
M_ASSERT (parent != NULL && !M_F(name, _is_leaf)(parent)); \
|
||||
M_ASSERT (0 <= k && k < M_F(name, _get_num)(parent)); \
|
||||
@@ -852,7 +846,7 @@
|
||||
M_ASSERT (left->num != 0); \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _right_shift)(node_t parent, int k) \
|
||||
M_INLINE void M_F(name, _right_shift)(node_t parent, int k) \
|
||||
{ \
|
||||
M_ASSERT (parent != NULL && !M_F(name, _is_leaf)(parent)); \
|
||||
M_ASSERT (0 <= k && k < M_F(name, _get_num)(parent)); \
|
||||
@@ -886,7 +880,7 @@
|
||||
M_ASSERT (left->num != 0); \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name, _merge_node)(node_t parent, int k, bool leaf) \
|
||||
M_INLINE void M_F(name, _merge_node)(node_t parent, int k, bool leaf) \
|
||||
{ \
|
||||
M_ASSERT (parent != NULL && !M_F(name, _is_leaf)(parent)); \
|
||||
M_ASSERT (0 <= k && k < M_F(name, _get_num(parent))); \
|
||||
@@ -921,7 +915,7 @@
|
||||
\
|
||||
/* We can also cache the index when we descend the tree. \
|
||||
TODO: Bench if this is worth the effort.*/ \
|
||||
static inline int \
|
||||
M_INLINE int \
|
||||
M_F(name, _search_for_node)(node_t parent, node_t child) \
|
||||
{ \
|
||||
M_ASSERT (!M_F(name, _is_leaf)(parent)); \
|
||||
@@ -934,7 +928,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool M_F(name, _erase)(tree_t b, key_t const key) \
|
||||
M_INLINE bool M_F(name, _erase)(tree_t b, key_t const key) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
pit_t pit; \
|
||||
@@ -990,7 +984,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool M_F(name, _pop_at)(value_t *ptr, tree_t b, key_t const key) \
|
||||
M_INLINE bool M_F(name, _pop_at)(value_t *ptr, tree_t b, key_t const key) \
|
||||
{ \
|
||||
if (ptr != NULL) { \
|
||||
value_t *ref = M_F(name, _get)(b, key); \
|
||||
@@ -1002,7 +996,7 @@
|
||||
return M_F(name, _erase)(b, key); \
|
||||
} \
|
||||
\
|
||||
static inline value_t * \
|
||||
M_INLINE value_t * \
|
||||
M_F(name, _min)(const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1015,7 +1009,7 @@
|
||||
return &n->M_IF(isMap)(kind.value, key)[0]; \
|
||||
} \
|
||||
\
|
||||
static inline value_t * \
|
||||
M_INLINE value_t * \
|
||||
M_F(name, _max)(const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1028,19 +1022,19 @@
|
||||
return &n->M_IF(isMap)(kind.value, key)[-n->num-1]; \
|
||||
} \
|
||||
\
|
||||
static inline value_t const * \
|
||||
M_INLINE value_t const * \
|
||||
M_F(name, _cmin)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_F(name, _min)(tree)); \
|
||||
} \
|
||||
\
|
||||
static inline value_t const * \
|
||||
M_INLINE value_t const * \
|
||||
M_F(name, _cmax)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_F(name, _max)(tree)); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(tree_t b, tree_t ref) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, ref); \
|
||||
@@ -1051,7 +1045,7 @@
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(tree_t b, tree_t ref) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1062,7 +1056,7 @@
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(tree_t tree1, tree_t tree2) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, tree1); \
|
||||
@@ -1076,7 +1070,7 @@
|
||||
/* Define iterator functions. */
|
||||
#define M_BPTR33_DEF_IT(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1090,7 +1084,7 @@
|
||||
it->idx = 0; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, const tree_t b) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1104,7 +1098,7 @@
|
||||
it->idx = -n->num; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t itd, const it_t its) \
|
||||
{ \
|
||||
M_ASSERT (itd != NULL && its != NULL); \
|
||||
@@ -1112,7 +1106,7 @@
|
||||
itd->idx = its->idx; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->node != NULL); \
|
||||
@@ -1120,13 +1114,13 @@
|
||||
return it->node->next ==NULL && it->idx >= -it->node->num; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const it_t it1, const it_t it2) \
|
||||
{ \
|
||||
return it1->node == it2->node && it1->idx == it2->idx; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->node != NULL); \
|
||||
@@ -1138,7 +1132,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline subtype_t * \
|
||||
M_INLINE subtype_t * \
|
||||
M_F(name, _ref)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->node != NULL); \
|
||||
@@ -1153,14 +1147,14 @@
|
||||
); \
|
||||
} \
|
||||
\
|
||||
static inline subtype_t const * \
|
||||
M_INLINE subtype_t const * \
|
||||
M_F(name, _cref)(it_t it) \
|
||||
{ \
|
||||
return M_CONST_CAST(subtype_t, M_F(name, _ref)(it)); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_from)(it_t it, const tree_t b, key_t const key) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -1181,7 +1175,7 @@
|
||||
it->idx = i; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_until_p)(it_t it, key_t const key) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1191,7 +1185,7 @@
|
||||
return (cmp >= 0); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_while_p)(it_t it, key_t const key) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1206,7 +1200,7 @@
|
||||
#define M_BPTR33_DEF_EXT(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(EQUAL, key_oplist, value_oplist)( \
|
||||
static inline bool M_F(name,_equal_p)(const tree_t t1, const tree_t t2) { \
|
||||
M_INLINE bool M_F(name,_equal_p)(const tree_t t1, const tree_t t2) { \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t2); \
|
||||
if (t1->size != t2->size) return false; \
|
||||
@@ -1242,7 +1236,7 @@
|
||||
, /* NO EQUAL METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(HASH, key_oplist, value_oplist)( \
|
||||
static inline size_t M_F(name,_hash)(const tree_t t1) { \
|
||||
M_INLINE size_t M_F(name,_hash)(const tree_t t1) { \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
M_HASH_DECL(hash); \
|
||||
/* NOTE: We can't compute the hash directly for the same reason \
|
||||
@@ -1264,7 +1258,7 @@
|
||||
, /* NO HASH METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(GET_STR, key_oplist, value_oplist)( \
|
||||
static inline void M_F(name, _get_str)(m_string_t str, \
|
||||
M_INLINE void M_F(name, _get_str)(m_string_t str, \
|
||||
const tree_t t1, bool append) { \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
M_ASSERT(str != NULL); \
|
||||
@@ -1292,7 +1286,7 @@
|
||||
, /* NO GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(OUT_STR, key_oplist, value_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, tree_t const t1) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
@@ -1320,7 +1314,7 @@
|
||||
, /* no out_str */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(PARSE_STR, key_oplist, value_oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(tree_t t1, const char str[], const char **endp) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
@@ -1362,7 +1356,7 @@
|
||||
, /* no parse_str */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(IN_STR, key_oplist, value_oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(tree_t t1, FILE *file) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
@@ -1400,7 +1394,7 @@
|
||||
, /* no in_str */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(OUT_SERIAL, key_oplist, value_oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, tree_t const t1) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
@@ -1444,7 +1438,7 @@
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(IN_SERIAL, key_oplist, value_oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(tree_t t1, m_serial_read_t f) \
|
||||
{ \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
|
||||
+92
-60
@@ -51,23 +51,53 @@ typedef enum {
|
||||
} m_buffer_policy_e;
|
||||
|
||||
|
||||
// TOMOVE to m-core
|
||||
#define M_DEF_AS(macro, ...) \
|
||||
M_BEGIN_PROTECTED_CODE \
|
||||
M_BY_NARGS(macro, __VA_ARGS__)(__VA_ARGS__) \
|
||||
M_END_PROTECTED_CODE
|
||||
|
||||
#define M_SIZE_AS(oplist, default) M_GET_METHOD(SIZE, default, M_OPFLAT oplist)
|
||||
#define M_POLICY_AS(oplist, default) M_GET_METHOD(POLICY, default, M_OPFLAT oplist)
|
||||
#define M_TYPE_AS(oplist, default) M_GET_METHOD(TYPE, default, M_OPFLAT oplist)
|
||||
#define M_TYPE2OPL(type) M_GLOBAL_OPLIST_OR_DEF(type)()
|
||||
|
||||
|
||||
/* Define a lock based buffer.
|
||||
If size is 0, then the size will only be defined at run-time when initializing the buffer,
|
||||
otherwise the size will be a compile time constant.
|
||||
USAGE: BUFFER_DEF(name, type, size_of_buffer_or_0, policy[, oplist]) */
|
||||
#define M_BUFFER_DEF(name, type, m_size, ... ) \
|
||||
M_BUFFER_DEF_AS(name, M_F(name, _t), type, m_size, __VA_ARGS__)
|
||||
|
||||
#define M_BUFFER_DEF(a, b, c, ... ) M_DEF_AS(M_BUFF3R_DEF, a, b, c, __VA_ARGS__)
|
||||
#define M_BUFF3R_DEF__4(n, t, s, p) M_BUFF3R_DEF_P1((n, t, s, p, M_TYPE2OPL(t), M_F(n, _t)))
|
||||
#define M_BUFF3R_DEF__5(n, t, s, p, o) M_BUFF3R_DEF_P1((n, t, s, p, o, M_F(n, _t)))
|
||||
#define M_BUFF3R_DEF__6(n, t, s, p, o)
|
||||
#define M_BUFF3R_DEF__7(n, t, s, p, o)
|
||||
#define M_BUFF3R_DEF__8(n, t, s, p, o)
|
||||
#define M_BUFF3R_DEF__9(n, t, s, p, o)
|
||||
|
||||
/* Define a lock based buffer
|
||||
as the provided type name_t.
|
||||
USAGE: BUFFER_DEF_AS(name, name_t, type, size_of_buffer_or_0, policy[, oplist of type]) */
|
||||
#define M_BUFFER_DEF_AS(name, name_t, type, m_size, ... ) \
|
||||
M_BEGIN_PROTECTED_CODE \
|
||||
M_BUFF3R_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||
((name, type, m_size,__VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(type)(), name_t ), \
|
||||
(name, type, m_size,__VA_ARGS__, name_t ))) \
|
||||
M_END_PROTECTED_CODE
|
||||
USAGE: BUFFER_DEF_AS(name, config_opl, type[, oplist of type]) */
|
||||
#define M_BUFFER_DEF_AS(a, b, ...) M_DEF_AS(M_BUFF3R_DEF_AS, a, b, __VA_ARGS__)
|
||||
#define M_BUFF3R_DEF_AS__3(n, c, t) M_BUFF3R_DEF_P1(M_BUFF3R_CONFIG(n, c, t, M_TYPE2OPL(t)))
|
||||
#define M_BUFF3R_DEF_AS__4(n, c, t, o) M_BUFF3R_DEF_P1(M_BUFF3R_CONFIG(n, c, t, o))
|
||||
#define M_BUFF3R_DEF_AS__5(n, c, t, o)
|
||||
#define M_BUFF3R_DEF_AS__6(n, c, t, o)
|
||||
#define M_BUFF3R_DEF_AS__7(n, c, t, o)
|
||||
#define M_BUFF3R_DEF_AS__8(n, c, t, o)
|
||||
#define M_BUFF3R_DEF_AS__9(n, c, t, o)
|
||||
|
||||
// Extract the optional customization attributes from name_opl
|
||||
#define M_BUFF3R_CONFIG(n, c, t, o) \
|
||||
(n, t, M_SIZE_AS(c, 0), M_POLICY_AS(c, M_BUFFER_QUEUE), o, M_TYPE_AS(c, M_C(n, _t)))
|
||||
|
||||
// Old call: (name, name_t, type, syze, policy [, oplist] )
|
||||
#define BUFFER_DEF_AS(a, b, c, d, ...) M_DEF_AS(M_BUFF3R_D3F_AS, a, b, c ,d, __VA_ARGS__)
|
||||
#define M_BUFF3R_D3F_AS__5(n, n_t, t, s, p) M_BUFF3R_DEF_P1((n, t, s, p, M_TYPE2OPL(type), n_t))
|
||||
#define M_BUFF3R_D3F_AS__6(n, n_t, t, s, p, o) M_BUFF3R_DEF_P1((n, t, s, p, o, n_t))
|
||||
#define M_BUFF3R_D3F_AS__7(n, n_t, t, s, p, o)
|
||||
#define M_BUFF3R_D3F_AS__8(n, n_t, t, s, p, o)
|
||||
#define M_BUFF3R_D3F_AS__9(n, n_t, t, s, p, o)
|
||||
|
||||
|
||||
/* Define the oplist of a lock based buffer given its name and its oplist.
|
||||
@@ -152,7 +182,7 @@ typedef union m_buff3r_number_s {
|
||||
#endif
|
||||
} m_buff3r_number_ct[1];
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_buff3r_number_init(m_buff3r_number_ct n, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -161,7 +191,7 @@ m_buff3r_number_init(m_buff3r_number_ct n, unsigned int policy)
|
||||
n->u = 0UL;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_buff3r_number_load(m_buff3r_number_ct n, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -172,7 +202,7 @@ m_buff3r_number_load(m_buff3r_number_ct n, unsigned int policy)
|
||||
return n->u;
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_buff3r_number_store(m_buff3r_number_ct n, unsigned int v, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -182,7 +212,7 @@ m_buff3r_number_store(m_buff3r_number_ct n, unsigned int v, unsigned int policy)
|
||||
n->u = v;
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_buff3r_number_set(m_buff3r_number_ct n, m_buff3r_number_ct v, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -192,7 +222,7 @@ m_buff3r_number_set(m_buff3r_number_ct n, m_buff3r_number_ct v, unsigned int pol
|
||||
n->u = v->u;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_buff3r_number_inc(m_buff3r_number_ct n, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -201,7 +231,7 @@ m_buff3r_number_inc(m_buff3r_number_ct n, unsigned int policy)
|
||||
return n->u ++;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
|
||||
{
|
||||
if (!M_BUFF3R_POLICY_P(policy, M_BUFFER_THREAD_UNSAFE))
|
||||
@@ -218,7 +248,7 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
|
||||
/* Return the size (run time or build time).
|
||||
NOTE: It assumed that the buffer variable name is 'v' */
|
||||
#define M_BUFF3R_SIZE(m_size) \
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size) (m_size, v->size)
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size) (m_size, v->capacity)
|
||||
|
||||
/* Contract of a buffer.
|
||||
Nothing particular since we cannot test much without locking it.
|
||||
@@ -235,7 +265,9 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
|
||||
|
||||
|
||||
/* Deferred evaluation for the definition,
|
||||
so that all arguments are evaluated before further expansion */
|
||||
so that all arguments are evaluated before further expansion
|
||||
USAGE: M_BUFF3R_DEF_P1 ( (name, type, m_size, policy, oplist, buffer_t) )
|
||||
*/
|
||||
#define M_BUFF3R_DEF_P1(arg) M_ID( M_BUFF3R_DEF_P2 arg )
|
||||
|
||||
/* Validate the value oplist before going further */
|
||||
@@ -277,7 +309,7 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
|
||||
size_t overwrite; /* Number of overwritten values */ \
|
||||
m_cond_t there_is_data; /* condition raised when there is data */ \
|
||||
/* Read only Data */ \
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)( ,size_t size;) /* Size of the buffer */ \
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)( ,size_t capacity;) /* Capacity of the buffer */ \
|
||||
/* Data for a consummer */ \
|
||||
m_cond_t there_is_room_for_data; /* Cond. raised when there is room */ \
|
||||
m_mutex_t mutexPop; /* MUTEX used for popping elements */ \
|
||||
@@ -300,11 +332,11 @@ m_buff3r_number_dec(m_buff3r_number_ct n, unsigned int policy)
|
||||
/* Define the core functionnalities of a buffer */
|
||||
#define M_BUFF3R_DEF_CORE(name, type, m_size, policy, oplist, buffer_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(buffer_t v, size_t size) \
|
||||
{ \
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)(M_ASSERT(size == m_size), v->size = size); \
|
||||
M_ASSERT(size <= UINT_MAX); \
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)(M_ASSERT(size == m_size), v->capacity = size); \
|
||||
v->idx_prod = v->idx_cons = v->overwrite = 0; \
|
||||
m_buff3r_number_init (v->number[0], policy); \
|
||||
if (M_BUFF3R_POLICY_P(policy, M_BUFFER_DEFERRED_POP)) \
|
||||
@@ -320,7 +352,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
\
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)( /* Statically allocated */ , \
|
||||
v->data = M_CALL_REALLOC(oplist, M_F(name, _el_ct), NULL, M_BUFF3R_SIZE(m_size)); \
|
||||
if (M_UNLIKELY_NOMEM (v->data == NULL)) { \
|
||||
if (M_UNLIKELY_NOMEM (v->data == NULL)) { \
|
||||
M_MEMORY_FULL (M_BUFF3R_SIZE(m_size)*sizeof(M_F(name, _el_ct))); \
|
||||
return; \
|
||||
} \
|
||||
@@ -334,14 +366,14 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
} \
|
||||
\
|
||||
M_BUFF3R_IF_CTE_SIZE(m_size)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_buff3r_,name,_init)(buffer_t v) \
|
||||
{ \
|
||||
M_F(name, _init)(v, m_size); \
|
||||
} \
|
||||
, ) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_buff3r_,name,_clear_obj)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -365,7 +397,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -383,7 +415,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -406,13 +438,13 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
} \
|
||||
\
|
||||
static inline void M_ATTR_DEPRECATED \
|
||||
M_INLINE void M_ATTR_DEPRECATED \
|
||||
M_F(name, _clean)(buffer_t v) \
|
||||
{ \
|
||||
M_F(name,_reset)(v); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(buffer_t dest, const buffer_t src) \
|
||||
{ \
|
||||
/* unconst 'src', so that we can lock it (semantically it is const) */ \
|
||||
@@ -456,7 +488,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_BUFF3R_CONTRACT(dest, m_size); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(buffer_t dest, const buffer_t src) \
|
||||
{ \
|
||||
/* unconst 'src', so that we can lock it (semantically it is const) */ \
|
||||
@@ -526,7 +558,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_BUFF3R_CONTRACT(dest, m_size); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -540,7 +572,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return m_buff3r_number_load (v->number[0], policy) == 0; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _full_p)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -548,14 +580,14 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
== M_BUFF3R_SIZE(m_size); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(buffer_t v) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
return m_buff3r_number_load (v->number[0], policy); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _push_blocking)(buffer_t v, type const data, bool blocking) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -635,7 +667,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop_blocking)(type *data, buffer_t v, bool blocking) \
|
||||
{ \
|
||||
M_BUFF3R_CONTRACT(v,m_size); \
|
||||
@@ -706,34 +738,34 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _push)(buffer_t v, type const data) \
|
||||
{ \
|
||||
return M_F(name, _push_blocking)(v, data, \
|
||||
!M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_PUSH)); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop)(type *data, buffer_t v) \
|
||||
{ \
|
||||
return M_F(name, _pop_blocking)(data, v, \
|
||||
!M_BUFF3R_POLICY_P((policy), M_BUFFER_UNBLOCKING_POP)); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _overwrite)(const buffer_t v) \
|
||||
{ \
|
||||
return v->overwrite; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(const buffer_t v) \
|
||||
{ \
|
||||
(void) v; /* may be unused */ \
|
||||
return M_BUFF3R_SIZE(m_size); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_release)(buffer_t v) \
|
||||
{ \
|
||||
/* Decrement the effective number of elements in the buffer */ \
|
||||
@@ -833,7 +865,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
|
||||
/* Define the core functionnalities of a MPMC queue */
|
||||
#define M_QU3UE_MPMC_DEF_CORE(name, type, policy, oplist, buffer_t) \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _push)(buffer_t table, type const x) \
|
||||
{ \
|
||||
M_QU3UE_MPMC_CONTRACT(table); \
|
||||
@@ -867,7 +899,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop)(type *ptr, buffer_t table) \
|
||||
{ \
|
||||
M_QU3UE_MPMC_CONTRACT(table); \
|
||||
@@ -896,7 +928,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(buffer_t buffer, size_t size) \
|
||||
{ \
|
||||
M_ASSERT (buffer != NULL); \
|
||||
@@ -920,7 +952,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_QU3UE_MPMC_CONTRACT(buffer); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(buffer_t buffer) \
|
||||
{ \
|
||||
M_QU3UE_MPMC_CONTRACT(buffer); \
|
||||
@@ -945,7 +977,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
buffer->size = 3; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(buffer_t table) \
|
||||
{ \
|
||||
M_QU3UE_MPMC_CONTRACT(table); \
|
||||
@@ -964,20 +996,20 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return iP-iC; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(buffer_t v) \
|
||||
{ \
|
||||
M_QU3UE_MPMC_CONTRACT(v); \
|
||||
return v->size; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(buffer_t v) \
|
||||
{ \
|
||||
return M_F(name, _size) (v) == 0; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _full_p)(buffer_t v) \
|
||||
{ \
|
||||
return M_F(name, _size)(v) >= v->size; \
|
||||
@@ -1060,7 +1092,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
/* Define the core functionnalities of a SPSC queue */
|
||||
#define M_QU3UE_SPSC_DEF_CORE(name, type, policy, oplist, buffer_t) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _push)(buffer_t table, type const x) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1081,7 +1113,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _push_move)(buffer_t table, type *x) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1102,7 +1134,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop)(type *ptr, buffer_t table) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1124,7 +1156,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline unsigned \
|
||||
M_INLINE unsigned \
|
||||
M_F(name, _push_bulk)(buffer_t table, unsigned n, type const x[]) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1150,7 +1182,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return max; \
|
||||
} \
|
||||
\
|
||||
static inline unsigned \
|
||||
M_INLINE unsigned \
|
||||
M_F(name, _pop_bulk)(unsigned int n, type ptr[], buffer_t table) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1176,7 +1208,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return max; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_force)(buffer_t table, type const x) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1199,7 +1231,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(buffer_t table) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(table); \
|
||||
@@ -1220,25 +1252,25 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
return w-r; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(buffer_t v) \
|
||||
{ \
|
||||
return v->size; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(buffer_t v) \
|
||||
{ \
|
||||
return M_F(name, _size) (v) == 0; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _full_p)(buffer_t v) \
|
||||
{ \
|
||||
return M_F(name, _size)(v) >= v->size; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(buffer_t buffer, size_t size) \
|
||||
{ \
|
||||
M_ASSERT (buffer != NULL); \
|
||||
@@ -1261,7 +1293,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
M_QU3UE_SPSC_CONTRACT(buffer); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(buffer_t buffer) \
|
||||
{ \
|
||||
M_QU3UE_SPSC_CONTRACT(buffer); \
|
||||
@@ -1323,7 +1355,7 @@ M_F(name, _init)(buffer_t v, size_t size) \
|
||||
|
||||
#if M_USE_SMALL_NAME
|
||||
#define BUFFER_DEF M_BUFFER_DEF
|
||||
#define BUFFER_DEF_AS M_BUFFER_DEF_AS
|
||||
//#define BUFFER_DEF_AS M_BUFFER_DEF_AS
|
||||
#define BUFFER_OPLIST M_BUFFER_OPLIST
|
||||
#define QUEUE_MPMC_DEF M_QUEUE_MPMC_DEF
|
||||
#define QUEUE_MPMC_DEF_AS M_QUEUE_MPMC_DEF_AS
|
||||
|
||||
+34
-34
@@ -53,13 +53,13 @@ M_BEGIN_PROTECTED_CODE
|
||||
\
|
||||
typedef struct M_F(name, _slist_node_s) *M_F(name, _slist_ct)[1]; \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _slist_init)(M_F(name, _slist_ct) list) \
|
||||
{ \
|
||||
*list = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _slist_push)(M_F(name, _slist_ct) list, \
|
||||
M_F(name, _slist_node_ct) *node) \
|
||||
{ \
|
||||
@@ -67,7 +67,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
*list = node; \
|
||||
} \
|
||||
\
|
||||
static inline M_F(name, _slist_node_ct) * \
|
||||
M_INLINE M_F(name, _slist_node_ct) * \
|
||||
M_F(name, _slist_pop)(M_F(name, _slist_ct) list) \
|
||||
{ \
|
||||
M_ASSERT (*list != NULL); \
|
||||
@@ -77,13 +77,13 @@ M_BEGIN_PROTECTED_CODE
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _slist_empty_p)(M_F(name, _slist_ct) list) \
|
||||
{ \
|
||||
return *list == NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _slist_move)(M_F(name, _slist_ct) list, \
|
||||
M_F(name, _slist_ct) src) \
|
||||
{ \
|
||||
@@ -91,7 +91,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
*src = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _slist_clear)(M_F(name, _slist_ct) list) \
|
||||
{ \
|
||||
M_F(name, _slist_node_ct) *it = *list, *next; \
|
||||
@@ -139,7 +139,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
M_F(name, _lf_node_t) nil; \
|
||||
} M_F(name, _lflist_ct)[1]; \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lflist_init)(M_F(name, _lflist_ct) list, \
|
||||
M_F(name, _lf_node_t) *node) \
|
||||
{ \
|
||||
@@ -148,13 +148,13 @@ M_BEGIN_PROTECTED_CODE
|
||||
atomic_store_explicit(&node->next, &list->nil, memory_order_relaxed); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _lflist_empty_p)(M_F(name, _lflist_ct) list) \
|
||||
{ \
|
||||
return atomic_load(&list->tail) == atomic_load(&list->head); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lflist_push)(M_F(name, _lflist_ct) list, \
|
||||
M_F(name, _lf_node_t) *node, m_core_backoff_ct bkoff) \
|
||||
{ \
|
||||
@@ -190,7 +190,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
memory_order_relaxed); \
|
||||
} \
|
||||
\
|
||||
static inline M_F(name, _lf_node_t) * \
|
||||
M_INLINE M_F(name, _lf_node_t) * \
|
||||
M_F(name, _lflist_pop)(M_F(name, _lflist_ct) list, m_core_backoff_ct bkoff) \
|
||||
{ \
|
||||
M_F(name, _lf_node_t) *head; \
|
||||
@@ -241,7 +241,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* Dequeue a node if the node is old enough */ \
|
||||
static inline M_F(name, _lf_node_t) * \
|
||||
M_INLINE M_F(name, _lf_node_t) * \
|
||||
M_F(name, _lflist_pop_if)(M_F(name, _lflist_ct) list, \
|
||||
m_gc_ticket_ct age, m_core_backoff_ct bkoff) \
|
||||
{ \
|
||||
@@ -281,7 +281,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
return head; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lflist_clear)(M_F(name, _lflist_ct) list) \
|
||||
{ \
|
||||
m_core_backoff_ct bkoff; \
|
||||
@@ -306,7 +306,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
As such it is a non Lock-Free path. */
|
||||
#define M_CMEMP00L_DEF_SYSTEM_ALLOC(name, type_t) \
|
||||
\
|
||||
static inline M_F(name, _lf_node_t) * \
|
||||
M_INLINE M_F(name, _lf_node_t) * \
|
||||
M_F(name, _alloc_node)(unsigned int initial) \
|
||||
{ \
|
||||
M_F(name, _lf_node_t) * node; \
|
||||
@@ -394,14 +394,14 @@ M_BEGIN_PROTECTED_CODE
|
||||
M_CACHELINE_ALIGN(align1, M_F(name, _slist_ct), M_F(name, _slist_ct)); \
|
||||
} M_F(name, _lfmp_thread_ct); \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lfmp_thread_init)(M_F(name, _lfmp_thread_ct) *t) \
|
||||
{ \
|
||||
M_F(name, _slist_init)(t->free); \
|
||||
M_F(name, _slist_init)(t->to_be_reclaimed); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lfmp_thread_clear)(M_F(name, _lfmp_thread_ct) *t) \
|
||||
{ \
|
||||
M_ASSERT(M_F(name, _slist_empty_p)(t->to_be_reclaimed)); \
|
||||
@@ -423,7 +423,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} M_F(name, _t)[1]; \
|
||||
\
|
||||
/* Garbage collect of the nodes of the mempool on sleep */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_cmemp00l_,name,_gc_on_sleep)(m_gc_t gc_mem, m_cmemp00l_list_ct *data, \
|
||||
m_gc_tid_t id, m_gc_ticket_ct ticket, m_gc_ticket_ct min_ticket) \
|
||||
{ \
|
||||
@@ -458,7 +458,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(M_F(name, _t) mem, m_gc_t gc_mem, \
|
||||
unsigned init_node_count, unsigned init_group_count) \
|
||||
{ \
|
||||
@@ -490,7 +490,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
mem->gc_mem = gc_mem; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(M_F(name, _t) mem) \
|
||||
{ \
|
||||
const unsigned max_thread = mem->gc_mem->max_thread; \
|
||||
@@ -506,7 +506,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
/* TODO: Unregister from the GC? */ \
|
||||
} \
|
||||
\
|
||||
static inline type_t * \
|
||||
M_INLINE type_t * \
|
||||
M_F(name, _new)(M_F(name, _t) mem, m_gc_tid_t id) \
|
||||
{ \
|
||||
M_F(name, _slist_node_ct) *snode; \
|
||||
@@ -533,7 +533,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _del)(M_F(name, _t) mem, type_t *d, m_gc_tid_t id) \
|
||||
{ \
|
||||
M_F(name, _slist_node_ct) *snode; \
|
||||
@@ -579,7 +579,7 @@ typedef struct m_gc_s {
|
||||
m_cmemp00l_list_ct *mempool_list;
|
||||
} m_gc_t[1];
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_gc_init(m_gc_t gc_mem, size_t max_thread)
|
||||
{
|
||||
M_ASSERT(gc_mem != NULL);
|
||||
@@ -600,7 +600,7 @@ m_gc_init(m_gc_t gc_mem, size_t max_thread)
|
||||
gc_mem->mempool_list = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_gc_clear(m_gc_t gc_mem)
|
||||
{
|
||||
M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0);
|
||||
@@ -613,7 +613,7 @@ m_gc_clear(m_gc_t gc_mem)
|
||||
m_genint_clear(gc_mem->thread_alloc);
|
||||
}
|
||||
|
||||
static inline m_gc_tid_t
|
||||
M_INLINE m_gc_tid_t
|
||||
m_gc_attach_thread(m_gc_t gc_mem)
|
||||
{
|
||||
M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0);
|
||||
@@ -622,7 +622,7 @@ m_gc_attach_thread(m_gc_t gc_mem)
|
||||
return M_ASSIGN_CAST(m_gc_tid_t, id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_gc_detach_thread(m_gc_t gc_mem, m_gc_tid_t id)
|
||||
{
|
||||
M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0);
|
||||
@@ -632,7 +632,7 @@ m_gc_detach_thread(m_gc_t gc_mem, m_gc_tid_t id)
|
||||
m_genint_push(gc_mem->thread_alloc, id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_gc_awake(m_gc_t gc_mem, m_gc_tid_t id)
|
||||
{
|
||||
M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0);
|
||||
@@ -643,7 +643,7 @@ m_gc_awake(m_gc_t gc_mem, m_gc_tid_t id)
|
||||
atomic_store(&gc_mem->thread_data[id].ticket, t);
|
||||
}
|
||||
|
||||
static inline m_gc_ticket_ct
|
||||
M_INLINE m_gc_ticket_ct
|
||||
m_cmemp00l_gc_min_ticket(m_gc_t gc_mem)
|
||||
{
|
||||
m_gc_ticket_ct min = atomic_load(&gc_mem->thread_data[0].ticket);
|
||||
@@ -654,7 +654,7 @@ m_cmemp00l_gc_min_ticket(m_gc_t gc_mem)
|
||||
return min;
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_gc_sleep(m_gc_t gc_mem, m_gc_tid_t id)
|
||||
{
|
||||
/* Increase life time of the thread */
|
||||
@@ -690,13 +690,13 @@ typedef struct m_vlapool_lfmp_thread_s {
|
||||
M_CACHELINE_ALIGN(align1, m_vlapool_slist_ct);
|
||||
} m_vlapool_lfmp_thread_ct;
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_vlapool_lfmp_thread_init(m_vlapool_lfmp_thread_ct *t)
|
||||
{
|
||||
m_vlapool_slist_init(t->to_be_reclaimed);
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_vlapool_lfmp_thread_clear(m_vlapool_lfmp_thread_ct *t)
|
||||
{
|
||||
M_ASSERT(m_vlapool_slist_empty_p(t->to_be_reclaimed));
|
||||
@@ -712,7 +712,7 @@ typedef struct m_vlapool_s {
|
||||
} m_vlapool_t[1];
|
||||
|
||||
/* Garbage collect of the nodes of the vla mempool on sleep */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_cmemp00l_vlapool_on_sleep(m_gc_t gc_mem, m_cmemp00l_list_ct *data,
|
||||
m_gc_tid_t id, m_gc_ticket_ct ticket, m_gc_ticket_ct min_ticket)
|
||||
{
|
||||
@@ -751,7 +751,7 @@ m_cmemp00l_vlapool_on_sleep(m_gc_t gc_mem, m_cmemp00l_list_ct *data,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_vlapool_init(m_vlapool_t mem, m_gc_t gc_mem)
|
||||
{
|
||||
const size_t max_thread = gc_mem->max_thread;
|
||||
@@ -777,7 +777,7 @@ m_vlapool_init(m_vlapool_t mem, m_gc_t gc_mem)
|
||||
mem->gc_mem = gc_mem;
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_vlapool_clear(m_vlapool_t mem)
|
||||
{
|
||||
const unsigned max_thread = mem->gc_mem->max_thread;
|
||||
@@ -792,7 +792,7 @@ m_vlapool_clear(m_vlapool_t mem)
|
||||
/* TODO: Unregister from the GC? */
|
||||
}
|
||||
|
||||
static inline void *
|
||||
M_INLINE void *
|
||||
m_vlapool_new(m_vlapool_t mem, m_gc_tid_t id, size_t size)
|
||||
{
|
||||
M_ASSERT(mem != NULL && mem->gc_mem != NULL);
|
||||
@@ -811,7 +811,7 @@ m_vlapool_new(m_vlapool_t mem, m_gc_tid_t id, size_t size)
|
||||
return (ptr == NULL) ? NULL : M_ASSIGN_CAST(void *, ptr + offsetof(struct m_vlapool_slist_node_s, data));
|
||||
}
|
||||
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_vlapool_del(m_vlapool_t mem, void *d, m_gc_tid_t id)
|
||||
{
|
||||
M_ASSERT(mem != NULL && mem->gc_mem != NULL);
|
||||
|
||||
+47
-50
@@ -130,9 +130,6 @@
|
||||
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
||||
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
|
||||
,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -196,7 +193,7 @@
|
||||
\
|
||||
/* Initial the fields of the concurrent object not associated to the \
|
||||
sub-container. */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _internal_init)(concurrent_t out) \
|
||||
{ \
|
||||
m_mutex_init(out->lock); \
|
||||
@@ -207,7 +204,7 @@
|
||||
\
|
||||
/* Clear the fields of the concurrent object not associated to the \
|
||||
sub-container. */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _internal_clear)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -220,7 +217,7 @@
|
||||
write lock is exclusive. \
|
||||
NOTE: This instance doesn't implement the read/write strategy, \
|
||||
and only get the lock */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_lock)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -230,7 +227,7 @@
|
||||
/* Free the read lock. See above. \
|
||||
NOTE: This instance doesn't implement the read/write strategy, \
|
||||
and only get the lock */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_unlock)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -239,7 +236,7 @@
|
||||
\
|
||||
/* Wait for a thread pushing some data in the container. \
|
||||
CONSTRAINT: the read lock shall be get before calling this service */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_wait)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -250,7 +247,7 @@
|
||||
can get the read lock too. \
|
||||
NOTE: This instance doesn't implement the read/write strategy, \
|
||||
and only get the lock */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_lock)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -260,7 +257,7 @@
|
||||
/* Free the write lock. \
|
||||
NOTE: This instance doesn't implement the read/write strategy, \
|
||||
and only get the lock */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_unlock)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -269,7 +266,7 @@
|
||||
\
|
||||
/* Wait for a thread pushing some data in the container. \
|
||||
CONSTRAINT: the write lock shall be get before calling this service */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_wait)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -278,7 +275,7 @@
|
||||
\
|
||||
/* Wait to all threads that some data are available in the container. \
|
||||
CONSTRAINT: the write lock shall be get before calling this service */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_signal)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -298,7 +295,7 @@
|
||||
#define M_C0NCURRENT_DEF_COMMON(name, type, oplist, concurrent_t) \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(concurrent_t out) \
|
||||
{ \
|
||||
M_F(name, _internal_init)(out); \
|
||||
@@ -308,7 +305,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(INIT_SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(concurrent_t out, concurrent_t const src) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(src); \
|
||||
@@ -322,7 +319,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(concurrent_t out, concurrent_t const src) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -357,7 +354,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(CLEAR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -369,7 +366,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(concurrent_t out, concurrent_t src) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(src); \
|
||||
@@ -383,7 +380,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(concurrent_t out, concurrent_t src) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -398,7 +395,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(SWAP, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(concurrent_t out, concurrent_t src) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -424,7 +421,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(RESET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -435,7 +432,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(EMPTY_P, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(concurrent_t const out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -447,7 +444,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(GET_SIZE, oplist)( \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(concurrent_t const out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -459,7 +456,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(SET_KEY, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set_at)(concurrent_t out, M_GET_KEY_TYPE oplist const key, M_GET_VALUE_TYPE oplist const data) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -471,7 +468,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(GET_KEY, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _get_copy)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -487,7 +484,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(SAFE_GET_KEY, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _safe_get_copy)(M_GET_VALUE_TYPE oplist *out_data, concurrent_t out, M_GET_KEY_TYPE oplist const key) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -501,7 +498,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(ERASE_KEY, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _erase)(concurrent_t out, M_GET_KEY_TYPE oplist const key) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -515,7 +512,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(PUSH, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push)(concurrent_t out, M_GET_SUBTYPE oplist const data) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -529,7 +526,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(POP, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -541,7 +538,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(PUSH_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_move)(concurrent_t out, M_GET_SUBTYPE oplist *data) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -553,7 +550,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(POP_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_move)(M_GET_SUBTYPE oplist *p, concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -565,7 +562,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(m_string_t str, concurrent_t const out, bool a) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -576,7 +573,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *f, concurrent_t const out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -587,7 +584,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(PARSE_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(concurrent_t out, const char str[], const char **e) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -600,7 +597,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(IN_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(concurrent_t out, FILE *f) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -613,7 +610,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, concurrent_t const out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -625,7 +622,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(IN_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(concurrent_t out, m_serial_read_t f) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -638,7 +635,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(concurrent_t const out1, concurrent_t const out2) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out1); \
|
||||
@@ -665,7 +662,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(GET_KEY, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _get_blocking)(M_GET_VALUE_TYPE oplist *out_data, const concurrent_t out, M_GET_KEY_TYPE oplist const key, bool blocking) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -689,7 +686,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD2(POP, EMPTY_P, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -712,7 +709,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD2(POP_MOVE, EMPTY_P, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop_move_blocking)(M_GET_SUBTYPE oplist *p, concurrent_t out, bool blocking) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -735,7 +732,7 @@
|
||||
,) \
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _hash)(concurrent_t const out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -795,7 +792,7 @@
|
||||
/* Define the internal services for the lock strategy of a RP container */
|
||||
#define M_C0NCURRENT_RP_DEF_CORE(name, type, oplist, concurrent_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _internal_init)(concurrent_t out) \
|
||||
{ \
|
||||
m_mutex_init(out->lock); \
|
||||
@@ -807,7 +804,7 @@
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _internal_clear)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -817,7 +814,7 @@
|
||||
out->self = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_lock)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -830,7 +827,7 @@
|
||||
m_mutex_unlock (self->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_unlock)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -843,7 +840,7 @@
|
||||
m_mutex_unlock (self->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_lock)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -858,7 +855,7 @@
|
||||
m_mutex_unlock (out->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_unlock)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -868,7 +865,7 @@
|
||||
m_mutex_unlock (out->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_wait)(const concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -887,7 +884,7 @@
|
||||
m_mutex_unlock (out->self->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_wait)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
@@ -905,7 +902,7 @@
|
||||
m_mutex_unlock (out->lock); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_signal)(concurrent_t out) \
|
||||
{ \
|
||||
M_C0NCURRENT_CONTRACT(out); \
|
||||
|
||||
@@ -264,6 +264,50 @@
|
||||
M_BEGIN_PROTECTED_CODE
|
||||
|
||||
|
||||
/************************************************************/
|
||||
/************************* LINKAGE **************************/
|
||||
/************************************************************/
|
||||
|
||||
/* The following semantics apply to inline in C99:
|
||||
- inline: No generation of an extern visible function. May inline or may call the external function.
|
||||
- extern inline: externally visible code is emitted, so at most one translation unit can use this.
|
||||
- static inline: No generation of an extern visible function. May inline or may call one static function.
|
||||
*/
|
||||
/* If the user requests to use only declaration for all M*LIB functions globally (M_USE_DECL),
|
||||
it requests no inlining to the compiler and emits code as weak symbol.
|
||||
Then at most one translation unit should request the definition of all functions (M_USE_DEF).
|
||||
This is only supported by GCC and CLANG. You should also use the options -ffunction-sections -fdata-sections -Wl,--gc-sections
|
||||
Otherwise it would increase the size of the executable.
|
||||
If M_USE_FINE_GRAINED_LINKAGE, then the mechanism can be turn on / off dynamically in compilation time
|
||||
to decl or def the functions in function of M_USE_DECL / M_USE_DEF
|
||||
Otherwise uses the classic "M_INLINE" (inline for C++ or static inline for C)
|
||||
inline in C++ as a weak definition by default, which may reduce code size in executable.
|
||||
*/
|
||||
#if !defined(__cplusplus) && defined(__GNUC__)
|
||||
# define M_INLINE_PRAGMA _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
|
||||
#else
|
||||
# define M_INLINE_PRAGMA
|
||||
#endif
|
||||
#if defined(__GNUC__) && defined(M_USE_FINE_GRAINED_LINKAGE)
|
||||
#define M_INLINE \
|
||||
M_IF_EMPTY(M_USE_DECL)( \
|
||||
M_IF_EMPTY(M_USE_DEF)(M_INLINE_PRAGMA __attribute__((noinline)) extern, \
|
||||
M_INLINE_PRAGMA __attribute__((weak, noinline)) extern), \
|
||||
static inline)
|
||||
#elif defined(__GNUC__) && defined(M_USE_DECL)
|
||||
# ifdef M_USE_DEF
|
||||
# define M_INLINE M_INLINE_PRAGMA __attribute__((noinline)) extern
|
||||
# else
|
||||
# define M_INLINE M_INLINE_PRAGMA __attribute__((weak, noinline)) extern
|
||||
#endif
|
||||
#elif defined(__cplusplus)
|
||||
#define M_INLINE inline
|
||||
#else
|
||||
#define M_INLINE static inline
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/************************************************************/
|
||||
/********************* MEMORY handling **********************/
|
||||
/************************************************************/
|
||||
@@ -449,48 +493,6 @@ M_BEGIN_PROTECTED_CODE
|
||||
#define M_UNLIKELY_NOMEM(cond) M_UNLIKELY(cond)
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/****************** Function Generation Macro ******************/
|
||||
/***************************************************************/
|
||||
|
||||
/*
|
||||
* Define the expansion logic to define a public / private / type function
|
||||
* for inline expansion
|
||||
*/
|
||||
#define M_EXPAND_FUNC_INLINE(proto, ...) \
|
||||
static inline proto __VA_ARGS__
|
||||
|
||||
#define M_EXPAND_FUNC_INLINE_PRIVATE(...) \
|
||||
__VA_ARGS__
|
||||
|
||||
#define M_EXPAND_FUNC_INLINE_TYPE(...) \
|
||||
__VA_ARGS__
|
||||
|
||||
/*
|
||||
* Define the expansion logic to define a public / private / type function
|
||||
* for inline expansion
|
||||
*/
|
||||
#define M_EXPAND_FUNC_DECL(proto, ...) \
|
||||
extern proto;
|
||||
|
||||
#define M_EXPAND_FUNC_DECL_PRIVATE(...)
|
||||
|
||||
#define M_EXPAND_FUNC_DECL_TYPE(...) \
|
||||
__VA_ARGS__
|
||||
|
||||
/*
|
||||
* Define the expansion logic to define a public / private / type function
|
||||
* for inline expansion
|
||||
*/
|
||||
#define M_EXPAND_FUNC_BODY(proto, ...) \
|
||||
proto __VA_ARGS__
|
||||
|
||||
#define M_EXPAND_FUNC_BODY_PRIVATE(...) \
|
||||
__VA_ARGS__
|
||||
|
||||
#define M_EXPAND_FUNC_BODY_TYPE(...)
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/****************** Preprocessing Times Macro ******************/
|
||||
/***************************************************************/
|
||||
@@ -2495,7 +2497,7 @@ done
|
||||
#define M_DEFAULTI_ARGS2(numArgs, numExpected, value, ...) \
|
||||
__VA_ARGS__ \
|
||||
M_IF(M_NOTEQUAL(numArgs, numExpected))(M_DEFERRED_COMMA, ) \
|
||||
M_REVERSE(M_KEEP_ARGS(M_SUB(numExpected, numArgs), M_REVERSE value, nothing))
|
||||
M_REVERSE(M_KEEP_ARGS(M_SUB(numExpected, numArgs), M_REVERSE value, M_LIB_ERROR_MISSING_MANDATORY_ARGUMENT))
|
||||
#define M_DEFAULTI_ARGS_EVAL(...) __VA_ARGS__
|
||||
#define M_DEFAULT_ARGS(expected, value, ...) \
|
||||
M_DEFAULTI_ARGS_EVAL(M_DEFAULTI_ARGS2(M_NARGS(__VA_ARGS__), expected, value, __VA_ARGS__))
|
||||
@@ -2574,7 +2576,7 @@ done
|
||||
#if defined(_MSC_VER) && defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
|
||||
|
||||
/* Wrapper around fopen_s */
|
||||
static inline FILE *
|
||||
M_INLINE FILE *
|
||||
m_core_fopen(const char filename[], const char opt[])
|
||||
{
|
||||
FILE *f;
|
||||
@@ -2663,7 +2665,7 @@ m_core_fopen(const char filename[], const char opt[])
|
||||
void *: false /* unsupported */)
|
||||
|
||||
/* Internal wrappers used by M_FSCAN_ARG : */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_core_fscan_bool (bool *ptr, FILE *f)
|
||||
{
|
||||
int c = fgetc(f);
|
||||
@@ -2671,7 +2673,7 @@ m_core_fscan_bool (bool *ptr, FILE *f)
|
||||
return (c == '0' || c == '1');
|
||||
}
|
||||
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_core_fscan_char (char *ptr, FILE *f)
|
||||
{
|
||||
int c = fgetc(f);
|
||||
@@ -2680,7 +2682,7 @@ m_core_fscan_char (char *ptr, FILE *f)
|
||||
}
|
||||
|
||||
#define M_FSCAN_DEFAULT_TYPE_DEF(name, type, format) \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
name (type *ptr, FILE *f) \
|
||||
{ \
|
||||
return m_core_fscanf(f, format, ptr) == 1; \
|
||||
@@ -2701,7 +2703,7 @@ M_FSCAN_DEFAULT_TYPE_DEF(m_core_fscan_ldouble, long double, "%Lf")
|
||||
|
||||
/* Return the next character (like fgetc) which is not a space character
|
||||
and advance the FILE stream accordingly */
|
||||
static inline int m_core_fgetc_nospace(FILE *f)
|
||||
M_INLINE int m_core_fgetc_nospace(FILE *f)
|
||||
{
|
||||
int c;
|
||||
do {
|
||||
@@ -2714,7 +2716,7 @@ static inline int m_core_fgetc_nospace(FILE *f)
|
||||
|
||||
/* Return the next character (like fgetc) which is not a space character
|
||||
and advance the string stream accordingly */
|
||||
static inline char m_core_str_nospace(const char **str)
|
||||
M_INLINE char m_core_str_nospace(const char **str)
|
||||
{
|
||||
char c;
|
||||
do {
|
||||
@@ -2754,7 +2756,7 @@ static inline char m_core_str_nospace(const char **str)
|
||||
void *: false /* not supported */)
|
||||
|
||||
/* Internal wrappers used by M_PARSE_DEFAULT_TYPE : */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_core_parse_char (char *ptr, const char str[], const char **endptr)
|
||||
{
|
||||
*ptr = *str++;
|
||||
@@ -2762,7 +2764,7 @@ m_core_parse_char (char *ptr, const char str[], const char **endptr)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_core_parse_bool (bool *ptr, const char str[], const char **endptr)
|
||||
{
|
||||
char c = *str++;
|
||||
@@ -2772,7 +2774,7 @@ m_core_parse_bool (bool *ptr, const char str[], const char **endptr)
|
||||
}
|
||||
|
||||
#define M_PARSE_DEFAULT_TYPE_DEF(name, type, parse_func, extra_arg) \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
name (type *ptr, const char str[], const char **endptr) \
|
||||
{ \
|
||||
char *end; \
|
||||
@@ -2908,7 +2910,7 @@ M_PARSE_DEFAULT_TYPE_DEF(m_core_parse_ldouble, long double, strtold, )
|
||||
# define M_MIN_FLEX_ARRAY_SIZE
|
||||
#endif
|
||||
|
||||
#if M_USE_STDARG
|
||||
#if M_USE_STDARG && M_USE_STDIO
|
||||
|
||||
/* Define the allocation of the temporary string used by M_CSTR
|
||||
Default is 256 bytes (so 255 characters excluding the final null char).
|
||||
@@ -2981,7 +2983,7 @@ namespace m_lib {
|
||||
#else
|
||||
|
||||
// Encapsulate snprintf to return the input buffer as argument (needed for M_CSTR)
|
||||
static inline const char *
|
||||
M_INLINE const char *
|
||||
m_core_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -3059,12 +3061,12 @@ m_core_snprintf(char *str, size_t size, const char *format, ...)
|
||||
return (x<<n) | (x>>(-n&31));
|
||||
but compilers are less likely to generate a roll instruction.
|
||||
*/
|
||||
static inline uint32_t m_core_rotl32a (uint32_t x, uint32_t n)
|
||||
M_INLINE uint32_t m_core_rotl32a (uint32_t x, uint32_t n)
|
||||
{
|
||||
M_ASSERT (n > 0 && n<32);
|
||||
return (x<<n) | (x>>(32-n));
|
||||
}
|
||||
static inline uint64_t m_core_rotl64a (uint64_t x, uint32_t n)
|
||||
M_INLINE uint64_t m_core_rotl64a (uint64_t x, uint32_t n)
|
||||
{
|
||||
M_ASSERT (n > 0 && n<64);
|
||||
return (x<<n) | (x>>(64-n));
|
||||
@@ -3073,7 +3075,7 @@ static inline uint64_t m_core_rotl64a (uint64_t x, uint32_t n)
|
||||
/* Round to the next highest power of 2.
|
||||
See https://web.archive.org/web/20160703165415/https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
*/
|
||||
static inline uint64_t m_core_roundpow2(uint64_t v)
|
||||
M_INLINE uint64_t m_core_roundpow2(uint64_t v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
@@ -3088,20 +3090,20 @@ static inline uint64_t m_core_roundpow2(uint64_t v)
|
||||
|
||||
/* Return the count leading zero of the argument */
|
||||
#if defined(__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__) >= 304
|
||||
static inline unsigned int m_core_clz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_clz32(uint32_t limb)
|
||||
{
|
||||
return (unsigned int) (M_UNLIKELY (limb == 0) ? sizeof(uint32_t)*CHAR_BIT : (size_t) __builtin_clzl(limb) - (sizeof(unsigned long) - sizeof(uint32_t)) * CHAR_BIT);
|
||||
}
|
||||
static inline unsigned int m_core_clz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_clz64(uint64_t limb)
|
||||
{
|
||||
return (unsigned int) (M_UNLIKELY (limb == 0ULL) ? sizeof (uint64_t)*CHAR_BIT : (size_t) __builtin_clzll(limb) - (sizeof (unsigned long long) - sizeof (uint64_t)) * CHAR_BIT);
|
||||
}
|
||||
|
||||
static inline unsigned int m_core_ctz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_ctz32(uint32_t limb)
|
||||
{
|
||||
return (unsigned int) (M_UNLIKELY (limb == 0) ? sizeof(uint32_t)*CHAR_BIT : (size_t) __builtin_ctzl(limb));
|
||||
}
|
||||
static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_ctz64(uint64_t limb)
|
||||
{
|
||||
return (unsigned int) (M_UNLIKELY (limb == 0ULL) ? sizeof (uint64_t)*CHAR_BIT : (size_t) __builtin_ctzll(limb));
|
||||
}
|
||||
@@ -3109,7 +3111,7 @@ static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
|
||||
// NOTE: _BitScanReverse64 is 64-bits only (not compatible 32 bits).
|
||||
#include <intrin.h>
|
||||
static inline unsigned int m_core_clz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_clz32(uint32_t limb)
|
||||
{
|
||||
unsigned long bit = 0;
|
||||
if (_BitScanReverse( &bit, limb ) != 0) {
|
||||
@@ -3118,7 +3120,7 @@ static inline unsigned int m_core_clz32(uint32_t limb)
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
static inline unsigned int m_core_clz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_clz64(uint64_t limb)
|
||||
{
|
||||
unsigned long bit = 0;
|
||||
if (_BitScanReverse64( &bit, limb ) != 0) {
|
||||
@@ -3128,7 +3130,7 @@ static inline unsigned int m_core_clz64(uint64_t limb)
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int m_core_ctz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_ctz32(uint32_t limb)
|
||||
{
|
||||
unsigned long bit = 0;
|
||||
if (_BitScanForward( &bit, limb ) != 0) {
|
||||
@@ -3137,7 +3139,7 @@ static inline unsigned int m_core_ctz32(uint32_t limb)
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_ctz64(uint64_t limb)
|
||||
{
|
||||
unsigned long bit = 0;
|
||||
if (_BitScanForward64( &bit, limb ) != 0) {
|
||||
@@ -3151,7 +3153,7 @@ static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
// Emulation layer
|
||||
#define M_CORE_CLZ_TAB "\010\07\06\06\05\05\05\05\04\04\04\04\04\04\04\04\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
|
||||
|
||||
static inline unsigned int m_core_clz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_clz32(uint32_t limb)
|
||||
{
|
||||
unsigned int shift = 0;
|
||||
/* This code should be branchless on most targets */
|
||||
@@ -3168,7 +3170,7 @@ static inline unsigned int m_core_clz32(uint32_t limb)
|
||||
return shift;
|
||||
}
|
||||
|
||||
static inline unsigned int m_core_clz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_clz64(uint64_t limb)
|
||||
{
|
||||
unsigned int shift = 0;
|
||||
/* This code should be branchless on most targets */
|
||||
@@ -3196,13 +3198,13 @@ static inline unsigned int m_core_clz64(uint64_t limb)
|
||||
/* See algorithm ctz5 that uses de Bruijn sequences to construct a minimal perfect hash function (32 bits) */
|
||||
#define M_CORE_CTZ_TAB "\000\001\034\002\035\016\030\003\036\026\024\017\031\021\004\010\037\033\015\027\025\023\020\007\032\014\022\006\013\005\012\011"
|
||||
|
||||
static inline unsigned int m_core_ctz32(uint32_t limb)
|
||||
M_INLINE unsigned int m_core_ctz32(uint32_t limb)
|
||||
{
|
||||
if (limb == 0) { return 32; }
|
||||
return (unsigned int) M_CORE_CTZ_TAB[ ( (uint32_t) (limb & -limb) * 0x077CB531) >> 27];
|
||||
}
|
||||
|
||||
static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
M_INLINE unsigned int m_core_ctz64(uint64_t limb)
|
||||
{
|
||||
unsigned int shift = 0;
|
||||
if ((limb & 0x0FFFFFFFFull) == 0) { shift = 32; limb >>= 32; }
|
||||
@@ -3224,7 +3226,7 @@ static inline unsigned int m_core_ctz64(uint64_t limb)
|
||||
*/
|
||||
#if SIZE_MAX <= 4294967295U
|
||||
/* 32 bits variant with an average measured avalanche effect of 16.056 bits */
|
||||
static inline uint32_t
|
||||
M_INLINE uint32_t
|
||||
m_core_hash (const void *str, size_t length)
|
||||
{
|
||||
const uint32_t prime = 709607U;
|
||||
@@ -3259,7 +3261,7 @@ m_core_hash (const void *str, size_t length)
|
||||
}
|
||||
#else
|
||||
/* 64 bits variant with an average measured avalanche effect of 31.862 bits */
|
||||
static inline uint64_t
|
||||
M_INLINE uint64_t
|
||||
m_core_hash (const void *str, size_t length)
|
||||
{
|
||||
const uint64_t prime = 1099511628211ULL;
|
||||
@@ -3305,7 +3307,7 @@ m_core_hash (const void *str, size_t length)
|
||||
* We cannot use m_core_hash due to the alignment constraint,
|
||||
* and it avoids computing the size before computing the hash.
|
||||
*/
|
||||
static inline size_t m_core_cstr_hash(const char str[])
|
||||
M_INLINE size_t m_core_cstr_hash(const char str[])
|
||||
{
|
||||
M_HASH_DECL(hash);
|
||||
while (*str) {
|
||||
@@ -3352,17 +3354,12 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_SET_SET(a) ,a,
|
||||
#define M_MOVE_MOVE(a) ,a,
|
||||
#define M_CLEAR_CLEAR(a) ,a,
|
||||
#define M_NEW_NEW(a) ,a,
|
||||
#define M_DEL_DEL(a) ,a,
|
||||
#define M_REALLOC_REALLOC(a) ,a,
|
||||
#define M_FREE_FREE(a) ,a,
|
||||
#define M_MEMPOOL_MEMPOOL(a) ,a,
|
||||
#define M_MEMPOOL_LINKAGE_MEMPOOL_LINKAGE(a) ,a,
|
||||
#define M_HASH_HASH(a) ,a,
|
||||
#define M_EQUAL_EQUAL(a) ,a,
|
||||
#define M_CMP_CMP(a) ,a,
|
||||
#define M_TYPE_TYPE(a) ,a,
|
||||
#define M_SUBTYPE_SUBTYPE(a) ,a,
|
||||
#define M_GENTYPE_GENTYPE(a) ,a,
|
||||
#define M_NAME_NAME(a) ,a,
|
||||
#define M_OPLIST_OPLIST(a) ,a,
|
||||
#define M_SORT_SORT(a) ,a,
|
||||
@@ -3416,10 +3413,19 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_LIMITS_LIMITS(a) ,a,
|
||||
#define M_PROPERTIES_PROPERTIES(a) ,a,
|
||||
#define M_EMPLACE_TYPE_EMPLACE_TYPE(a) ,a,
|
||||
|
||||
// Properties only
|
||||
// As attribute customization
|
||||
#define M_NEW_NEW(a) ,a,
|
||||
#define M_DEL_DEL(a) ,a,
|
||||
#define M_REALLOC_REALLOC(a) ,a,
|
||||
#define M_FREE_FREE(a) ,a,
|
||||
#define M_MEMPOOL_MEMPOOL(a) ,a,
|
||||
#define M_MEMPOOL_LINKAGE_MEMPOOL_LINKAGE(a) ,a,
|
||||
#define M_SIZE_SIZE(a) ,a,
|
||||
#define M_CONTEXT_CONTEXT(a) ,a,
|
||||
#define M_POLICY_POLICY(a) ,a,
|
||||
// As properties only
|
||||
#define M_LET_AS_INIT_WITH_LET_AS_INIT_WITH(a) ,a,
|
||||
#define M_NOCLEAR_NOCLEAR(a) ,a,
|
||||
#define M_NOCLEAR_NOCLEAR(a) ,a,
|
||||
|
||||
/* From an oplist - an unorded list of methods : like "INIT(mpz_init),CLEAR(mpz_clear),SET(mpz_set)" -
|
||||
Return the given method in the oplist or the default method.
|
||||
@@ -3438,17 +3444,12 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_GET_MOVE(...) M_GET_METHOD(MOVE, M_NO_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_SWAP(...) M_GET_METHOD(SWAP, M_NO_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_CLEAR(...) M_GET_METHOD(CLEAR, M_NOTHING_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_NEW(...) M_GET_METHOD(NEW, M_NEW_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_DEL(...) M_GET_METHOD(DEL, M_DEL_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_REALLOC(...) M_GET_METHOD(REALLOC, M_REALLOC_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_FREE(...) M_GET_METHOD(FREE, M_FREE_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_MEMPOOL(...) M_GET_METHOD(MEMPOOL, M_NO_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_MEMPOOL_LINKAGE(...) M_GET_METHOD(MEMPOOL_LINKAGE, , __VA_ARGS__)
|
||||
#define M_GET_HASH(...) M_GET_METHOD(HASH, M_NO_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_EQUAL(...) M_GET_METHOD(EQUAL, M_EQUAL_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_CMP(...) M_GET_METHOD(CMP, M_CMP_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_TYPE(...) M_GET_METHOD(TYPE, M_NO_DEF_TYPE, __VA_ARGS__)
|
||||
#define M_GET_SUBTYPE(...) M_GET_METHOD(SUBTYPE, M_NO_DEF_TYPE, __VA_ARGS__)
|
||||
#define M_GET_GENTYPE(...) M_GET_METHOD(GENTYPE, M_NO_DEF_TYPE, __VA_ARGS__)
|
||||
#define M_GET_NAME(...) M_GET_METHOD(NAME, M_NO_DEF_TYPE, __VA_ARGS__)
|
||||
#define M_GET_OPLIST(...) M_GET_METHOD(OPLIST, (), __VA_ARGS__)
|
||||
#define M_GET_SORT(...) M_GET_METHOD(SORT, M_NO_DEFAULT, __VA_ARGS__)
|
||||
@@ -3502,6 +3503,16 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_GET_LIMITS(...) M_GET_METHOD(LIMITS, M_LIMITS_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_PROPERTIES(...) M_GET_METHOD(PROPERTIES, (), __VA_ARGS__)
|
||||
#define M_GET_EMPLACE_TYPE(...) M_GET_METHOD(EMPLACE_TYPE, M_NO_DEFAULT, __VA_ARGS__)
|
||||
// As sttribute customization
|
||||
#define M_GET_NEW(...) M_GET_METHOD(NEW, M_NEW_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_DEL(...) M_GET_METHOD(DEL, M_DEL_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_REALLOC(...) M_GET_METHOD(REALLOC, M_REALLOC_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_FREE(...) M_GET_METHOD(FREE, M_FREE_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_MEMPOOL(...) M_GET_METHOD(MEMPOOL, M_NO_DEFAULT, __VA_ARGS__)
|
||||
#define M_GET_MEMPOOL_LINKAGE(...) M_GET_METHOD(MEMPOOL_LINKAGE, , __VA_ARGS__)
|
||||
#define M_GET_SIZE(...) M_GET_METHOD(SIZE, 0, __VA_ARGS__)
|
||||
#define M_GET_CONTEXT(...) M_GET_METHOD(CONTEXT, 0, __VA_ARGS__)
|
||||
#define M_GET_POLICY(...) M_GET_METHOD(POLICY, 0, __VA_ARGS__)
|
||||
|
||||
// Calling method with support of defined transformation API
|
||||
// operators that are not methods are commented
|
||||
@@ -3514,16 +3525,12 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_CALL_SWAP(oplist, ...) M_APPLY_API(M_GET_SWAP oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_CLEAR(oplist, ...) M_APPLY_API(M_GET_CLEAR oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_NEW(oplist, ...) M_APPLY_API(M_GET_NEW oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_DEL(oplist, ...) M_APPLY_API(M_GET_DEL oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_REALLOC(oplist, ...) M_APPLY_API(M_GET_REALLOC oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_FREE(oplist, ...) M_APPLY_API(M_GET_FREE oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_MEMPOOL(oplist, ...) M_APPLY_API(M_GET_MEMPOOL oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_MEMPOOL_LINKAGE(oplist, ...) M_APPLY_API(M_GET_MEMPOOL_LINKAGE oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_HASH(oplist, ...) M_APPLY_API(M_GET_HASH oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_EQUAL(oplist, ...) M_APPLY_API(M_GET_EQUAL oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_CMP(oplist, ...) M_APPLY_API(M_GET_CMP oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_TYPE(oplist, ...) M_APPLY_API(M_GET_TYPE oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_SUBTYPE(oplist, ...) M_APPLY_API(M_GET_SUBTYPE oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_GENTYPE(oplist, ...) M_APPLY_API(M_GET_GENTYPE oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_NAME(oplist, ...) M_APPLY_API(M_GET_NAME oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_OPLIST(oplist, ...) M_APPLY_API(M_GET_OPLIST oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_SORT(oplist, ...) M_APPLY_API(M_GET_SORT oplist, oplist, __VA_ARGS__)
|
||||
@@ -3573,6 +3580,15 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
//#define M_CALL_LIMITS(oplist, ...) M_APPLY_API(M_GET_LIMITS oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_PROPERTIES(oplist, ...) M_APPLY_API(M_GET_PROPERTIES oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_EMPLACE_TYPE(oplist, ...) M_APPLY_API(M_GET_EMPLACE_TYPE oplist, oplist, __VA_ARGS__)
|
||||
// As attribute customization
|
||||
#define M_CALL_DEL(oplist, ...) M_APPLY_API(M_GET_DEL oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_REALLOC(oplist, ...) M_APPLY_API(M_GET_REALLOC oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_FREE(oplist, ...) M_APPLY_API(M_GET_FREE oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_MEMPOOL(oplist, ...) M_APPLY_API(M_GET_MEMPOOL oplist, oplist, __VA_ARGS__)
|
||||
#define M_CALL_MEMPOOL_LINKAGE(oplist, ...) M_APPLY_API(M_GET_MEMPOOL_LINKAGE oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_SIZE(oplist, ...) M_APPLY_API(M_GET_SIZE oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_CONTEXT(oplist, ...) M_APPLY_API(M_GET_CONTEXT oplist, oplist, __VA_ARGS__)
|
||||
//#define M_CALL_POLICY(oplist, ...) M_APPLY_API(M_GET_POLICY oplist, oplist, __VA_ARGS__)
|
||||
|
||||
|
||||
/* API transformation support:
|
||||
@@ -3774,7 +3790,7 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_CHECK_COMPATIBLE_OPLIST(name, inst, type, oplist) \
|
||||
M_IF_METHOD(TYPE, oplist) \
|
||||
( \
|
||||
static inline void M_C3(m_c0re_ctype_, name, inst)(void) \
|
||||
M_INLINE void M_C3(m_c0re_ctype_, name, inst)(void) \
|
||||
{ \
|
||||
type x; \
|
||||
/* Proper check using _Generic */ \
|
||||
@@ -3791,7 +3807,7 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
#define M_CHECK_COMPATIBLE_OPLIST(name, inst, type, oplist) \
|
||||
M_IF_METHOD(TYPE, oplist) \
|
||||
( \
|
||||
static inline void M_C3(m_c0re_ctype_, name, inst)(void) \
|
||||
M_INLINE void M_C3(m_c0re_ctype_, name, inst)(void) \
|
||||
{ \
|
||||
/* Imperfect check using size of type */ \
|
||||
M_STATIC_ASSERT(sizeof (type) == sizeof (M_GET_TYPE oplist), \
|
||||
@@ -3986,7 +4002,7 @@ static inline size_t m_core_cstr_hash(const char str[])
|
||||
/* Input/Output an enumerate.
|
||||
It is stored as a long long integer for best compatibility. */
|
||||
#if M_USE_STDIO
|
||||
static inline long long
|
||||
M_INLINE long long
|
||||
m_core_fscan_enum (FILE *f)
|
||||
{
|
||||
long long ret;
|
||||
@@ -4003,12 +4019,12 @@ m_core_fscan_enum (FILE *f)
|
||||
|
||||
/* HACK: Parse two times to convert and then compute
|
||||
if the conversion succeeds for PARSE */
|
||||
static inline long long
|
||||
M_INLINE long long
|
||||
m_core_parse1_enum (const char str[])
|
||||
{
|
||||
return strtoll(str, NULL, 10);
|
||||
}
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_core_parse2_enum (const char str[], const char **endptr)
|
||||
{
|
||||
char *end;
|
||||
@@ -4332,6 +4348,12 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
#define M_LET_TRY_INJECT_PRE(cont, oplist, name)
|
||||
#define M_LET_TRY_INJECT_POST(cont, oplist, name)
|
||||
|
||||
/*
|
||||
Internal M_LET for use for withing container.
|
||||
*/
|
||||
#define M_QLET(x, type, oplist) \
|
||||
M_LET(x, M_OPEXTEND(oplist, TYPE(type)))
|
||||
|
||||
/* Transform the va list by adding their number as the first argument of
|
||||
the list.
|
||||
Example: M_VA(a,b,c,d,e) ==> 5,a,b,c,d,e
|
||||
@@ -4362,6 +4384,112 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
#define M_DEFER_TRY_INJECT_POST(cont, clear) /* Nothing */
|
||||
|
||||
|
||||
/* If exceptions are activated, M_CHAIN_INIT enables support for chaining
|
||||
initialization at the begining of a constructor for the fields of the constructed
|
||||
object so that even if the constructor failed and throw an exception,
|
||||
the fields of the constructed object are properly cleared.
|
||||
This is equivalent to C++ construct: void type() : field1(), field2() { rest of constructor }
|
||||
M_CHAIN_INIT shall be the first instruction of the init function.
|
||||
Second argument is the initialization code.
|
||||
Third argument is the clear code.
|
||||
The clear code is *only* executed on exception.
|
||||
USAGE:
|
||||
void init_function(struct_t s) {
|
||||
M_CHAIN_INIT(name, string_init(s->str), string_clear(s->str)) {
|
||||
// Rest of initialization code
|
||||
}
|
||||
}
|
||||
*/
|
||||
#define M_CHAIN_INIT(name, init, clear) \
|
||||
M_CHAIN_INIT_INTERNAL(M_C(m_var_, name), init, clear)
|
||||
|
||||
#define M_CHAIN_INIT_INTERNAL(cont, init, clear) \
|
||||
for(bool cont = true; cont; cont = false) \
|
||||
M_DEFER_TRY_INJECT_PRE(cont, clear) \
|
||||
for( init; cont ; cont = false) \
|
||||
M_DEFER_TRY_INJECT_POST(cont, clear) \
|
||||
for( (void) 0; cont; cont = false)
|
||||
|
||||
|
||||
/* If exceptions are activated, M_CHAIN_OBJ enables support for chaining
|
||||
initialization at the begining of a constructor for the fields of the constructed
|
||||
object so that even if the constructor failed and throw an exception,
|
||||
the fields of the constructed object are properly cleared.
|
||||
This is equivalent to M_CHAIN_INIT except it takes an oplist.
|
||||
This is equivalent to C++ construct: void type() : field1(), field2() { rest of constructor }
|
||||
M_CHAIN_OBJ shall be the first instruction of the init function except
|
||||
it can be freely mixed with M_CHAIN_INIT
|
||||
First argument is a name identifier.
|
||||
Second argument is the oplist of the variable to initialize.
|
||||
Third argument is the variable to initialize.
|
||||
Optional fourth argument is the value to use for initialization.
|
||||
If there is no value, it will initialize using the INIT method.
|
||||
Otherwise, if there is no parenthesis around the value, it will use the INIT_SET method.
|
||||
Otherwise the INIT_WITH method.
|
||||
The clear code is *only* executed on exception.
|
||||
If the property NOCLEAR is defined for the object,
|
||||
it won't generate an exception handler at all even if exceptions are activated,
|
||||
and will only initialize the object.
|
||||
USAGE:
|
||||
void init_function(struct_t s) {
|
||||
M_CHAIN_OBJ(name, STRING_OPLIST, s->str ) {
|
||||
// Rest of initialization code
|
||||
}
|
||||
}
|
||||
*/
|
||||
#define M_CHAIN_OBJ(name, oplist, ...) \
|
||||
M_BY_NARGS( M_IF(M_GET_PROPERTY(oplist, NOCLEAR))(M_CHAIN_OBJ_A, M_CHAIN_OBJ_B), __VA_ARGS__) \
|
||||
(name, oplist, __VA_ARGS__)
|
||||
// Need to define an exception handler. Use of M_CHAIN_INIT
|
||||
#define M_CHAIN_OBJ_B__1(name, oplist, var) \
|
||||
M_CHAIN_INIT( name, M_CALL_INIT(oplist, var), M_CALL_CLEAR(oplist, var) )
|
||||
#define M_CHAIN_OBJ_B__2(name, oplist, var, value) \
|
||||
M_IF(M_PARENTHESIS_P(value))(M_CHAIN_OBJ_B__2_WITH, M_CHAIN_OBJ_B__2_SET) \
|
||||
(name, oplist, var, value)
|
||||
#define M_CHAIN_OBJ_B__2_WITH(name, oplist, var, value) \
|
||||
M_CHAIN_INIT( name, M_CALL_INIT_WITH(oplist, var, value), M_CALL_CLEAR(oplist, var) )
|
||||
#define M_CHAIN_OBJ_B__2_SET(name, oplist, var, value) \
|
||||
M_CHAIN_INIT( name, M_CALL_INIT_SET(oplist, var, value), M_CALL_CLEAR(oplist, var) )
|
||||
// No need to define an exception handler. Just call the INIT function.
|
||||
#define M_CHAIN_OBJ_A__1(name, oplist, var) \
|
||||
M_CHAIN_FOR(name, M_CALL_INIT(oplist, var) )
|
||||
#define M_CHAIN_OBJ_A__2(name, oplist, var, value) \
|
||||
M_CHAIN_FOR(name, \
|
||||
M_IF(M_PARENTHESIS_P(value))(M_CALL_INIT_WITH, M_CALL_INIT_SET) \
|
||||
(oplist, var, value) )
|
||||
|
||||
// Execute the 'init' function in a for loop construct
|
||||
#define M_CHAIN_FOR(name, init ) \
|
||||
M_CHAIN_FOR_B(M_C(m_var_, name), init)
|
||||
#define M_CHAIN_FOR_B(cont, init) \
|
||||
for(bool cont = true; cont; cont = false) \
|
||||
for( init; cont ; cont = false) \
|
||||
for( (void) 0; cont; cont = false)
|
||||
|
||||
|
||||
/* If exceptions are activated, M_ON_EXCEPTION enables support for fixing
|
||||
the data structure when an exception is throw,
|
||||
so that the data structure is proper for the CLEAR method.
|
||||
The fix code is *only* executed on exception.
|
||||
USAGE:
|
||||
void init_function(struct_t s) {
|
||||
M_ON_EXCEPTION(name, OPLIST, s->size = i ) {
|
||||
// Rest of initialization code
|
||||
}
|
||||
}
|
||||
*/
|
||||
#define M_ON_EXCEPTION(name, oplist, fix) \
|
||||
M_IF(M_GET_PROPERTY(oplist, NOCLEAR))(M_EAT, M_ON_EXCEPTION_B) \
|
||||
(M_C(m_var_, name), fix)
|
||||
|
||||
#define M_ON_EXCEPTION_B(cont, fix) \
|
||||
for(bool cont = true; cont; cont = false) \
|
||||
M_DEFER_TRY_INJECT_PRE(cont, clear) \
|
||||
for( ; cont ; cont = false) \
|
||||
M_DEFER_TRY_INJECT_POST(cont, clear) \
|
||||
for( ; cont; cont = false)
|
||||
|
||||
|
||||
/* Declare a variable, initialize it, continue if the initialization succeeds,
|
||||
and clears the variable afterwards.
|
||||
Otherwise, stop the execution and execute else_code if defined.
|
||||
@@ -4389,18 +4517,21 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
/******************* INIT_WITH Enhancing ********************/
|
||||
/************************************************************/
|
||||
|
||||
/* Add as suffix for the given function the number of arguments of the calls.
|
||||
Can be used to call different function in function of the number of arguments. */
|
||||
#define M_SUFFIX_FUNCTION_BY_NARGS(function, ...) M_C3(function, _, M_NARGS(__VA_ARGS__))
|
||||
/* Add as suffix for the given function the number of arguments of the calls
|
||||
equal to __ # NARGS(...)
|
||||
Can be used to call different function in function of the number of arguments.
|
||||
It doesn't call the function with the argument in order to be able to chain the
|
||||
macro */
|
||||
#define M_BY_NARGS(function, ...) M_C3(function, __, M_NARGS(__VA_ARGS__))
|
||||
|
||||
/* Call different INIT_WITH method in function of the number of arguments of the call,
|
||||
* to be used in an OPLIST.
|
||||
/* Call different methods in function of the number of arguments of the call,
|
||||
* to be used in an OPLIST for the INIT_WITH operator.
|
||||
* Shall be used with API_1 call (example INIT_WITH(API_1(M_INIT_WITH_NVAR)) )
|
||||
* Shall define a NAME base method
|
||||
* All INIT_WITH methods shall be named as name ## _init_with_ ## NARGS
|
||||
* All INIT_WITH methods shall be named as name ## _init_with__ ## NARGS
|
||||
*/
|
||||
#define M_INIT_WITH_NVAR(oplist, ...) \
|
||||
M_SUFFIX_FUNCTION_BY_NARGS(M_C(M_GET_NAME oplist, _init_with), __VA_ARGS__)(__VA_ARGS__)
|
||||
M_BY_NARGS(M_C(M_GET_NAME oplist, _init_with), __VA_ARGS__)(__VA_ARGS__)
|
||||
|
||||
|
||||
/* Initialize the container 'dest' as per 'oplist' INIT operator
|
||||
@@ -4464,10 +4595,6 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
)
|
||||
#define M_INIT_EMPLACE_VAI2_FUNC(pair, a) \
|
||||
M_INIT_EMPLACE_VAI3_FUNC(M_PAIR_1 pair, M_PAIR_2 pair, a)
|
||||
|
||||
/* We first push a raw new item, and then we get back its pointer using _back.
|
||||
_back (contrary to _push_raw) has no side effect, and so is safe to be used
|
||||
in a macro */
|
||||
#define M_INIT_EMPLACE_VAI3_FUNC(d, op, a) \
|
||||
( \
|
||||
M_IF(M_PARENTHESIS_P(a)) \
|
||||
@@ -4772,7 +4899,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
one for value only.
|
||||
*/
|
||||
#define M_EMPLACE_ASS_ARRA1_BOTH_GENE(name, name_t, function_name, key_oplist, val_oplist, key_init_func, val_init_func, key_emplace_type, val_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \
|
||||
M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \
|
||||
@@ -4787,7 +4914,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
} \
|
||||
|
||||
#define M_EMPLACE_ASS_ARRA1_KEY_GENE(name, name_t, function_name, key_oplist, val_oplist, key_init_func, val_init_func, key_emplace_type, val_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(akey, key_emplace_type) \
|
||||
, M_F(name, _value_ct) const val \
|
||||
@@ -4799,7 +4926,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
} \
|
||||
|
||||
#define M_EMPLACE_ASS_ARRA1_VAL_GENE(name, name_t, function_name, key_oplist, val_oplist, key_init_func, val_init_func, key_emplace_type, val_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v, M_F(name, _key_ct) const key \
|
||||
M_EMPLACE_LIST_TYPE_VAR(aval, val_emplace_type) \
|
||||
){ \
|
||||
@@ -4815,7 +4942,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
This definition is far from being efficient but works for the current interface.
|
||||
*/
|
||||
#define M_EMPLACE_QUEUE_GENE(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -4831,7 +4958,7 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
This definition is far from being efficient but works for the current interface.
|
||||
*/
|
||||
#define M_EMPLACE_GET_GENE(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline M_F(name, _value_ct) * \
|
||||
M_INLINE M_F(name, _value_ct) * \
|
||||
function_name(name_t const v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -4867,7 +4994,7 @@ typedef struct m_core_backoff_s {
|
||||
/* Initialize a backoff object.
|
||||
* Use the C function rand to initialize its internal seed.
|
||||
* It should be good enough for the purpose of the backoff */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_core_backoff_init(m_core_backoff_ct backoff)
|
||||
{
|
||||
backoff->count = 0;
|
||||
@@ -4875,7 +5002,7 @@ m_core_backoff_init(m_core_backoff_ct backoff)
|
||||
}
|
||||
|
||||
/* Reset the count of the backoff object */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_core_backoff_reset(m_core_backoff_ct backoff)
|
||||
{
|
||||
backoff->count = 0;
|
||||
@@ -4884,7 +5011,7 @@ m_core_backoff_reset(m_core_backoff_ct backoff)
|
||||
/* Wait a few nanoseconds using an active loop,
|
||||
* generating a random number of nanosecond to wait,
|
||||
* and increment the number of times wait has been called */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_core_backoff_wait(m_core_backoff_ct backoff)
|
||||
{
|
||||
/* x is qualified as volatile to avoid being optimized away
|
||||
@@ -4903,7 +5030,7 @@ m_core_backoff_wait(m_core_backoff_ct backoff)
|
||||
}
|
||||
|
||||
/* Clear the backoff object */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_core_backoff_clear(m_core_backoff_ct backoff)
|
||||
{
|
||||
// Nothing to do
|
||||
@@ -4923,9 +5050,10 @@ struct m_string_s;
|
||||
* - OK & done (object is fully parsed),
|
||||
* - OK & continue parsing (object is partially parsed)
|
||||
* - Fail parsing
|
||||
* - Fail parsing with given arguments (give explicit size)
|
||||
*/
|
||||
typedef enum m_serial_return_code_e {
|
||||
M_SERIAL_OK_DONE = 0, M_SERIAL_OK_CONTINUE = 1, M_SERIAL_FAIL = 2
|
||||
M_SERIAL_OK_DONE = 0, M_SERIAL_OK_CONTINUE = 1, M_SERIAL_FAIL = 2, M_SERIAL_FAIL_RETRY = 4
|
||||
} m_serial_return_code_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -5106,7 +5234,7 @@ typedef struct m_serial_write_interface_s {
|
||||
/* Helper functions for M_IN_SERIAL_DEFAULT_ARG
|
||||
as we need to define a function per supported type in the generic expression */
|
||||
#define M_IN_SERIAL_DEFAULT_TYPE_DEF(name, type, func, promoted_type) \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
name (m_serial_read_t serial, type *ptr) \
|
||||
{ \
|
||||
promoted_type i; \
|
||||
@@ -5132,7 +5260,7 @@ M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_double, double, read_float, long d
|
||||
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_ldouble, long double, read_float, long double)
|
||||
|
||||
/* Helper function for M_ENUM_IN_SERIAL */
|
||||
static inline long long
|
||||
M_INLINE long long
|
||||
m_core_in_serial_enum(m_serial_read_t serial)
|
||||
{
|
||||
long long i;
|
||||
@@ -5145,7 +5273,7 @@ m_core_in_serial_enum(m_serial_read_t serial)
|
||||
* because of expanded code will call strlen with NULL (which is illegal)
|
||||
* However, the branch where it is called is unreachable, so the warning
|
||||
* is not justified. */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_core_out_serial_strlen(const char s[])
|
||||
{
|
||||
M_ASSERT(s != NULL);
|
||||
@@ -5157,7 +5285,7 @@ m_core_out_serial_strlen(const char s[])
|
||||
* M_SERIAL_FAIL
|
||||
* so that a breakpoint can be put on this function for debugging purpose.
|
||||
*/
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_core_serial_fail(void)
|
||||
{
|
||||
return M_SERIAL_FAIL;
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
#define M_D3QU3_DEF_CORE(name, type, oplist, deque_t, it_t, node_t) \
|
||||
\
|
||||
/* Allocate a new node for a deque */ \
|
||||
static inline node_t* \
|
||||
M_INLINE node_t* \
|
||||
M_C3(m_d3qu3_,name,_new_node)(deque_t d) \
|
||||
{ \
|
||||
size_t def = d->default_size; \
|
||||
@@ -198,7 +198,7 @@
|
||||
return n; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(deque_t d) \
|
||||
{ \
|
||||
M_F(name, _node_list_init)(d->list); \
|
||||
@@ -214,7 +214,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -239,7 +239,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -252,7 +252,7 @@
|
||||
d->count = 0; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_back_raw)(deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -279,13 +279,13 @@
|
||||
} \
|
||||
\
|
||||
/* Internal, for INIT_WITH */ \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_raw)(deque_t d) \
|
||||
{ \
|
||||
return M_F(name, _push_back_raw)(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_back)(deque_t d, type const x) \
|
||||
{ \
|
||||
type *p = M_F(name, _push_back_raw)(d); \
|
||||
@@ -295,7 +295,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_back_new)(deque_t d) \
|
||||
{ \
|
||||
type *p = M_F(name, _push_back_raw)(d); \
|
||||
@@ -306,7 +306,7 @@
|
||||
} \
|
||||
, ) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_back_move)(deque_t d, type *x) \
|
||||
{ \
|
||||
M_ASSERT (x != NULL); \
|
||||
@@ -316,7 +316,7 @@
|
||||
M_DO_INIT_MOVE (oplist, *p, *x); \
|
||||
} \
|
||||
\
|
||||
static inline type* \
|
||||
M_INLINE type* \
|
||||
M_F(name, _push_front_raw)(deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -341,7 +341,7 @@
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_front)(deque_t d, type const x) \
|
||||
{ \
|
||||
type *p = M_F(name, _push_front_raw)(d); \
|
||||
@@ -351,7 +351,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _push_front_new)(deque_t d) \
|
||||
{ \
|
||||
type *p = M_F(name, _push_front_raw)(d); \
|
||||
@@ -362,7 +362,7 @@
|
||||
} \
|
||||
,) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_front_move)(deque_t d, type *x) \
|
||||
{ \
|
||||
M_ASSERT (x != NULL); \
|
||||
@@ -372,7 +372,7 @@
|
||||
M_DO_INIT_MOVE (oplist, *p, *x); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_back)(type *ptr, deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -408,7 +408,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_back_move)(type *ptr, deque_t d) \
|
||||
{ \
|
||||
M_ASSERT(ptr != NULL); \
|
||||
@@ -418,7 +418,7 @@
|
||||
} \
|
||||
, ) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_front)(type *ptr, deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -464,7 +464,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop_front_move)(type *ptr, deque_t d) \
|
||||
{ \
|
||||
M_ASSERT(ptr != NULL); \
|
||||
@@ -474,7 +474,7 @@
|
||||
} \
|
||||
,) \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _back)(const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -489,7 +489,7 @@
|
||||
return &n->data[i-1]; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _front)(const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -499,14 +499,14 @@
|
||||
return &n->data[i]; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
return d->count; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity_back)(const deque_t v) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(v); \
|
||||
@@ -520,7 +520,7 @@
|
||||
return s; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity_front)(const deque_t v) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(v); \
|
||||
@@ -534,20 +534,20 @@
|
||||
return s; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(const deque_t v) \
|
||||
{ \
|
||||
return M_F(name, _capacity_back)(v)+M_F(name, _capacity_front)(v); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
return d->count == 0; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -557,7 +557,7 @@
|
||||
it->deque = d; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(it_t it, const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -572,7 +572,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -582,7 +582,7 @@
|
||||
it->deque = d; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t it1, const it_t it2) \
|
||||
{ \
|
||||
M_ASSERT (it1 != NULL); \
|
||||
@@ -592,7 +592,7 @@
|
||||
it1->deque = it2->deque; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -602,7 +602,7 @@
|
||||
&& it->index < it->deque->front->index); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -621,7 +621,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -640,7 +640,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -650,7 +650,7 @@
|
||||
return M_F(name, _end_p)(it2); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(it_t it1, const it_t it2) \
|
||||
{ \
|
||||
M_ASSERT (it1 != NULL); \
|
||||
@@ -660,7 +660,7 @@
|
||||
&& it1->index == it2->index; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -668,7 +668,7 @@
|
||||
return &it->node->data[it->index]; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -676,7 +676,7 @@
|
||||
return M_CONST_CAST(type, &it->node->data[it->index]); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove)(deque_t d, it_t it) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -739,7 +739,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(deque_t d, const deque_t src) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(src); \
|
||||
@@ -766,7 +766,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(deque_t d, deque_t const src) \
|
||||
{ \
|
||||
if (M_UNLIKELY (src == d)) \
|
||||
@@ -776,7 +776,7 @@
|
||||
M_F(name, _init_set)(d, src); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(deque_t d, deque_t src) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(src); \
|
||||
@@ -792,7 +792,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(deque_t d, deque_t src) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -802,7 +802,7 @@
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(deque_t d, deque_t e) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -818,7 +818,7 @@
|
||||
M_D3QU3_CONTRACT(e); \
|
||||
} \
|
||||
\
|
||||
static inline type* \
|
||||
M_INLINE type* \
|
||||
M_F(name, _get)(deque_t d, size_t key) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -837,13 +837,13 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cget)(deque_t d, size_t key) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_F(name, _get)(d, key)); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set_at)(deque_t d, size_t key, type const x) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -854,7 +854,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(const deque_t d1, const deque_t d2) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d1); \
|
||||
@@ -877,7 +877,7 @@
|
||||
, /* NO EQUAL */) \
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _hash)(const deque_t d) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -892,7 +892,7 @@
|
||||
, /* NO HASH */) \
|
||||
\
|
||||
M_IF_METHOD(SWAP, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap_at)(deque_t d, size_t i, size_t j) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(d); \
|
||||
@@ -906,7 +906,7 @@
|
||||
, /* NO SWAP */) \
|
||||
\
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(m_string_t str, deque_t const deque, bool append) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -925,7 +925,7 @@
|
||||
, /* no GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, const deque_t deque) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -945,7 +945,7 @@
|
||||
, /* no OUT_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD2(PARSE_STR, INIT, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(deque_t deque, const char str[], const char **endp) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -977,7 +977,7 @@
|
||||
, /* no PARSE_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD2(IN_STR, INIT, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(deque_t deque, FILE *file) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -1004,7 +1004,7 @@
|
||||
, /* no IN_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, const deque_t deque) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -1029,7 +1029,7 @@
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
\
|
||||
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(deque_t deque, m_serial_read_t f) \
|
||||
{ \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
@@ -1055,7 +1055,7 @@
|
||||
|
||||
/* Definition of the emplace_back function for deque */
|
||||
#define M_D3QUE_EMPLACE_BACK_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1068,7 +1068,7 @@
|
||||
|
||||
/* Definition of the emplace_front function for deque */
|
||||
#define M_D3QUE_EMPLACE_FRONT_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t v \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1133,9 +1133,6 @@
|
||||
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
||||
,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),) \
|
||||
,M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@
|
||||
typedef value_type M_F(name, _value_ct); \
|
||||
typedef dict_it_t M_F(name, _it_ct); \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(dict_t map) \
|
||||
{ \
|
||||
M_ASSERT (map != NULL); \
|
||||
@@ -345,7 +345,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(dict_t map, const dict_t org) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, org); \
|
||||
@@ -357,7 +357,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(dict_t map, const dict_t org) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
@@ -369,14 +369,14 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_clear)(dict_t map) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
M_F(name, _array_list_pair_clear)(map->table); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(dict_t map, dict_t org) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, org); \
|
||||
@@ -387,7 +387,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(dict_t d1, dict_t d2) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, d1); \
|
||||
@@ -400,7 +400,7 @@
|
||||
M_D1CT_CONTRACT(name, d2); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(dict_t map, dict_t org) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
@@ -411,7 +411,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_reset)(dict_t map) \
|
||||
{ \
|
||||
M_F(name, _array_list_pair_reset)(map->table); \
|
||||
@@ -422,7 +422,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline value_type * \
|
||||
M_INLINE value_type * \
|
||||
M_F(name, _get)(const dict_t map, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
@@ -442,13 +442,13 @@
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static inline value_type const * \
|
||||
M_INLINE value_type const * \
|
||||
M_F(name, _cget)(const dict_t map, key_type const key) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_type, M_F(name,_get)(map,key)); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_d1ct_,name,_resize_up)(dict_t map) \
|
||||
{ \
|
||||
/* NOTE: Contract may not be fulfilled here */ \
|
||||
@@ -488,7 +488,7 @@
|
||||
map->lower_limit = M_D1CT_LOWER_BOUND(new_size); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_d1ct_,name,_resize_down)(dict_t map) \
|
||||
{ \
|
||||
/* NOTE: Contract may not be fulfilled here */ \
|
||||
@@ -513,7 +513,7 @@
|
||||
map->lower_limit = M_D1CT_LOWER_BOUND(new_size); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_IF(isSet)(M_F(name, _push), M_F(name, _set_at)) \
|
||||
(dict_t map, key_type const key \
|
||||
M_IF(isSet)(, M_DEFERRED_COMMA value_type const value)) \
|
||||
@@ -545,7 +545,7 @@
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
} \
|
||||
\
|
||||
static inline value_type * \
|
||||
M_INLINE value_type * \
|
||||
M_F(name, _safe_get)(dict_t map, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
@@ -578,7 +578,7 @@
|
||||
return &(*ref)->M_IF(isSet)(key, value); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _erase)(dict_t map, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, map); \
|
||||
@@ -606,7 +606,7 @@
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(dict_it_t it, const dict_t d) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, d); \
|
||||
@@ -623,7 +623,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(dict_it_t it, const dict_it_t ref) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && ref != NULL); \
|
||||
@@ -632,21 +632,21 @@
|
||||
M_F(name, _list_pair_it_set)(it->list_it, ref->list_it); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(dict_it_t it, const dict_t d) \
|
||||
{ \
|
||||
M_D1CT_CONTRACT(name, d); \
|
||||
M_F(name, _array_list_pair_it_end)(it->array_it, d->table); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
return M_F(name, _list_pair_end_p)(it->list_it); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
@@ -661,7 +661,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -671,7 +671,7 @@
|
||||
return M_F(name, _end_p)(it2); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const dict_it_t it1, const dict_it_t it2) \
|
||||
{ \
|
||||
M_ASSERT (it1 != NULL && it2 != NULL); \
|
||||
@@ -679,7 +679,7 @@
|
||||
it2->list_it); \
|
||||
} \
|
||||
\
|
||||
static inline it_deref_t * \
|
||||
M_INLINE it_deref_t * \
|
||||
M_F(name, _ref)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
@@ -692,7 +692,7 @@
|
||||
) \
|
||||
} \
|
||||
\
|
||||
static inline const it_deref_t * \
|
||||
M_INLINE const it_deref_t * \
|
||||
M_F(name, _cref)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
@@ -733,14 +733,14 @@
|
||||
*/
|
||||
#define M_D1CT_FUNC_ADDITIONAL_DEF2(name, key_type, key_oplist, value_type, value_oplist, isSet, dict_t, dict_it_t, it_deref_t) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name,_empty_p)(const dict_t map) \
|
||||
{ \
|
||||
M_ASSERT(map != NULL); \
|
||||
return map->count == 0; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name,_size)(const dict_t map) \
|
||||
{ \
|
||||
M_ASSERT(map != NULL); \
|
||||
@@ -748,7 +748,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, value_oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(const dict_t dict1, const dict_t dict2) \
|
||||
{ \
|
||||
M_ASSERT (dict1 != NULL && dict2 != NULL); \
|
||||
@@ -778,7 +778,7 @@
|
||||
, /* no value equal */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(GET_STR, key_oplist, value_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(m_string_t str, const dict_t dict, const bool append) \
|
||||
{ \
|
||||
(append ? m_string_cat_cstr : m_string_set_cstr) (str, "{"); \
|
||||
@@ -804,7 +804,7 @@
|
||||
, /* no GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(OUT_STR, key_oplist, value_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, const dict_t dict) \
|
||||
{ \
|
||||
M_ASSERT (file != NULL); \
|
||||
@@ -831,7 +831,7 @@
|
||||
, /* no OUT_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(PARSE_STR, key_oplist, value_oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(dict_t dict, const char str[], const char **endp) \
|
||||
{ \
|
||||
M_ASSERT (str != NULL); \
|
||||
@@ -876,7 +876,7 @@
|
||||
, /* no PARSE_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(IN_STR, key_oplist, value_oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(dict_t dict, FILE *file) \
|
||||
{ \
|
||||
M_ASSERT (file != NULL); \
|
||||
@@ -918,7 +918,7 @@
|
||||
, /* no IN_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(OUT_SERIAL, key_oplist, value_oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, dict_t const t1) \
|
||||
{ \
|
||||
M_ASSERT (f != NULL && f->m_interface != NULL); \
|
||||
@@ -961,7 +961,7 @@
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
\
|
||||
M_IF_METHOD_BOTH(IN_SERIAL, key_oplist, value_oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(dict_t t1, m_serial_read_t f) \
|
||||
{ \
|
||||
M_ASSERT (f != NULL && f->m_interface != NULL); \
|
||||
@@ -1003,7 +1003,7 @@
|
||||
, /* no in_serial */ ) \
|
||||
\
|
||||
M_IF(isSet)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice)(dict_t d1, dict_t d2) \
|
||||
{ \
|
||||
dict_it_t it; \
|
||||
@@ -1018,7 +1018,7 @@
|
||||
} \
|
||||
, \
|
||||
M_IF_METHOD(ADD, value_oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice)(dict_t d1, dict_t d2) \
|
||||
{ \
|
||||
dict_it_t it; \
|
||||
@@ -1098,9 +1098,6 @@
|
||||
,M_IF_METHOD_BOTH(OUT_SERIAL, key_oplist, value_oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
|
||||
,M_IF_METHOD_BOTH(IN_SERIAL, key_oplist, value_oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
||||
,M_IF_METHOD(EQUAL, value_oplist)(EQUAL(M_F(name, _equal_p)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW key_oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC key_oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL key_oplist),) \
|
||||
)
|
||||
|
||||
/* Deferred evaluation for the definition,
|
||||
@@ -1157,9 +1154,6 @@
|
||||
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
|
||||
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
||||
,EQUAL(M_F(name, _equal_p)), \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
/* Define Lower Bound for hash table (TODO: Common macro for both implementation) */
|
||||
@@ -1297,7 +1291,7 @@ enum m_d1ct_oa_element_e {
|
||||
typedef value_type M_F(name, _value_ct); \
|
||||
typedef dict_it_t M_F(name, _it_ct); \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_d1ct_,name,_update_limit)(dict_t dict, size_t size) \
|
||||
{ \
|
||||
/* FIXME: Overflow not handled. What to do in case of it? */ \
|
||||
@@ -1305,7 +1299,7 @@ enum m_d1ct_oa_element_e {
|
||||
dict->lower_limit = (size <= M_D1CT_INITIAL_SIZE) ? 0 : (size_t) ((double) size * coeff_down) ; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(dict_t dict) \
|
||||
{ \
|
||||
M_ASSERT(0 <= (coeff_down) && (coeff_down)*2 < (coeff_up) && (coeff_up) < 1); \
|
||||
@@ -1326,7 +1320,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(dict_t dict) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
@@ -1343,7 +1337,7 @@ enum m_d1ct_oa_element_e {
|
||||
dict->data = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline value_type * \
|
||||
M_INLINE value_type * \
|
||||
M_F(name, _get)(const dict_t dict, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
@@ -1374,14 +1368,14 @@ enum m_d1ct_oa_element_e {
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static inline value_type const * \
|
||||
M_INLINE value_type const * \
|
||||
M_F(name, _cget)(const dict_t map, key_type const key) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_type, M_F(name,_get)(map,key)); \
|
||||
} \
|
||||
\
|
||||
M_IF_DEBUG( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C3(m_d1ct_,name,_control_after_resize)(const dict_t h) \
|
||||
{ \
|
||||
/* This function checks if the reshashing of the dict is ok */ \
|
||||
@@ -1399,7 +1393,7 @@ enum m_d1ct_oa_element_e {
|
||||
} \
|
||||
) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_d1ct_,name,_resize_up)(dict_t h, size_t newSize, bool updateLimit) \
|
||||
{ \
|
||||
size_t oldSize = h->mask+1; \
|
||||
@@ -1477,7 +1471,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(h); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_IF(isSet)(M_F(name, _push), M_F(name,_set_at)) \
|
||||
(dict_t dict, key_type const key \
|
||||
M_IF(isSet)(, M_DEFERRED_COMMA value_type const value) ) \
|
||||
@@ -1537,7 +1531,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
} \
|
||||
\
|
||||
static inline value_type * \
|
||||
M_INLINE value_type * \
|
||||
M_F(name,_safe_get)(dict_t dict, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
@@ -1593,13 +1587,13 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
return &data[p].M_IF(isSet)(key, value); \
|
||||
} \
|
||||
static inline M_ATTR_DEPRECATED value_type * \
|
||||
M_INLINE M_ATTR_DEPRECATED value_type * \
|
||||
M_F(name,_get_at)(dict_t dict, key_type const key) \
|
||||
{ \
|
||||
return M_F(name,_safe_get)(dict, key); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_d1ct_,name,_resize_down)(dict_t h, size_t newSize) \
|
||||
{ \
|
||||
size_t oldSize = h->mask+1; \
|
||||
@@ -1677,7 +1671,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(h); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name,_erase)(dict_t dict, key_type const key) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
@@ -1713,7 +1707,7 @@ enum m_d1ct_oa_element_e {
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(dict_t map, const dict_t org) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(org); \
|
||||
@@ -1741,7 +1735,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(dict_t map, const dict_t org) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
@@ -1753,7 +1747,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(dict_t map, dict_t org) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(org); \
|
||||
@@ -1770,7 +1764,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(dict_t map, dict_t org) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
@@ -1782,7 +1776,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(map); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(dict_t d1, dict_t d2) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(d1); \
|
||||
@@ -1797,7 +1791,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(d2); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(dict_t d) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(d); \
|
||||
@@ -1821,13 +1815,13 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT(d); \
|
||||
} \
|
||||
\
|
||||
static inline void M_ATTR_DEPRECATED \
|
||||
M_INLINE void M_ATTR_DEPRECATED \
|
||||
M_F(name, _clean)(dict_t d) \
|
||||
{ \
|
||||
M_F(name, _reset)(d); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(dict_it_t it, const dict_t d) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(d); \
|
||||
@@ -1842,7 +1836,7 @@ enum m_d1ct_oa_element_e {
|
||||
it->index = i; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(dict_it_t it, const dict_it_t ref) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1852,7 +1846,7 @@ enum m_d1ct_oa_element_e {
|
||||
M_D1CT_OA_CONTRACT (it->dict); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(dict_it_t it, const dict_t d) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(d); \
|
||||
@@ -1867,7 +1861,7 @@ enum m_d1ct_oa_element_e {
|
||||
it->index = i; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(dict_it_t it, const dict_t d) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(d); \
|
||||
@@ -1876,7 +1870,7 @@ enum m_d1ct_oa_element_e {
|
||||
it->index = d->mask+1; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1884,7 +1878,7 @@ enum m_d1ct_oa_element_e {
|
||||
return it->index > it->dict->mask; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1898,7 +1892,7 @@ enum m_d1ct_oa_element_e {
|
||||
it->index = i; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1913,7 +1907,7 @@ enum m_d1ct_oa_element_e {
|
||||
it->index = i; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1923,7 +1917,7 @@ enum m_d1ct_oa_element_e {
|
||||
return M_F(name, _end_p)(it2); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const dict_it_t it1,const dict_it_t it2) \
|
||||
{ \
|
||||
M_ASSERT (it1 != NULL && it2 != NULL); \
|
||||
@@ -1932,7 +1926,7 @@ enum m_d1ct_oa_element_e {
|
||||
return it1->dict == it2->dict && it1->index == it2->index; \
|
||||
} \
|
||||
\
|
||||
static inline it_deref_t * \
|
||||
M_INLINE it_deref_t * \
|
||||
M_F(name, _ref)(const dict_it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -1944,13 +1938,13 @@ enum m_d1ct_oa_element_e {
|
||||
return &it->dict->data[i] M_IF(isSet)(.key, ); \
|
||||
} \
|
||||
\
|
||||
static inline const it_deref_t * \
|
||||
M_INLINE const it_deref_t * \
|
||||
M_F(name, _cref)(const dict_it_t it) \
|
||||
{ \
|
||||
return M_CONST_CAST(it_deref_t, M_F(name, _ref)(it)); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_reserve)(dict_t dict, size_t capacity) \
|
||||
{ \
|
||||
M_D1CT_OA_CONTRACT(dict); \
|
||||
|
||||
+12
-12
@@ -161,7 +161,7 @@
|
||||
/* Internal type for oplist & instance */ \
|
||||
typedef interface_t M_F(name, _ct); \
|
||||
\
|
||||
static inline retcode \
|
||||
M_INLINE retcode \
|
||||
M_F(name, _call)(interface_t funcobj) \
|
||||
{ \
|
||||
M_IF(M_KEYWORD_P(void, retcode)) ( /* nothing */,return) \
|
||||
@@ -197,7 +197,7 @@
|
||||
/* Internal type for oplist & instance */ \
|
||||
typedef interface_t M_F(name, _ct); \
|
||||
\
|
||||
static inline retcode \
|
||||
M_INLINE retcode \
|
||||
M_F(name, _call)(interface_t funcobj \
|
||||
M_MAP3(M_FUNC0BJ_BASE_ARGLIST, name, __VA_ARGS__) ) \
|
||||
{ \
|
||||
@@ -220,7 +220,7 @@
|
||||
/* Internal type for oplist */ \
|
||||
typedef instance_t M_F(name, _ct); \
|
||||
\
|
||||
static inline M_C(base_name, _retcode_ct) \
|
||||
M_INLINE M_C(base_name, _retcode_ct) \
|
||||
M_F(name, _callback)(M_C(base_name, _ct) _self \
|
||||
M_IF_EMPTY(M_OPFLAT param_list)( \
|
||||
/* No param */, \
|
||||
@@ -233,25 +233,25 @@
|
||||
callback_core; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_with)(instance_t obj) \
|
||||
{ \
|
||||
obj->callback = M_F(name, _callback); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(instance_t obj) \
|
||||
{ \
|
||||
(void) obj; /* nothing to do */ \
|
||||
} \
|
||||
\
|
||||
static inline struct M_C(base_name, _s) * \
|
||||
M_INLINE struct M_C(base_name, _s) * \
|
||||
M_F(name, _as_interface)(instance_t obj) \
|
||||
{ \
|
||||
return (struct M_C(base_name, _s) *) obj; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(instance_t obj) \
|
||||
{ \
|
||||
obj->callback = M_F(name, _callback); \
|
||||
@@ -306,7 +306,7 @@
|
||||
\
|
||||
M_FUNC0BJ_CONTROL_ALL_OPLIST(name, __VA_ARGS__) \
|
||||
\
|
||||
static inline M_C(base_name, _retcode_ct) \
|
||||
M_INLINE M_C(base_name, _retcode_ct) \
|
||||
M_F(name, _callback)(M_C(base_name, _ct) _self \
|
||||
M_IF_EMPTY(M_OPFLAT param_list)( \
|
||||
/* No param */, \
|
||||
@@ -321,20 +321,20 @@
|
||||
callback_core; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_with)(instance_t obj M_MAP(M_FUNC0BJ_INS_ATTR_LIST, __VA_ARGS__)) \
|
||||
{ \
|
||||
obj->callback = M_F(name, _callback); \
|
||||
M_MAP(M_FUNC0BJ_INS_ATTR_INIT_SET, __VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(instance_t obj) \
|
||||
{ \
|
||||
M_MAP(M_FUNC0BJ_INS_ATTR_CLEAR, __VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
static inline struct M_C(base_name, _s) * \
|
||||
M_INLINE struct M_C(base_name, _s) * \
|
||||
M_F(name, _as_interface)(instance_t obj) \
|
||||
{ \
|
||||
return (struct M_C(base_name, _s) *) obj; \
|
||||
@@ -342,7 +342,7 @@
|
||||
\
|
||||
M_IF(M_FUNC0BJ_TEST_METHOD_P(INIT, __VA_ARGS)) \
|
||||
( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(instance_t obj) \
|
||||
{ \
|
||||
obj->callback = M_F(name, _callback); \
|
||||
|
||||
+5
-5
@@ -103,7 +103,7 @@ typedef struct m_genint_s {
|
||||
* meaning it can be used to index global unique resources shared
|
||||
* for all threads.
|
||||
*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_genint_init(m_genint_t s, unsigned int n)
|
||||
{
|
||||
M_ASSERT (s != NULL && n > 0 && n <= M_GENINT_MAX_ALLOC);
|
||||
@@ -126,7 +126,7 @@ m_genint_init(m_genint_t s, unsigned int n)
|
||||
}
|
||||
|
||||
/* Clear an integer generator (Destructor) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_genint_clear(m_genint_t s)
|
||||
{
|
||||
M_GEN1NT_CONTRACT(s);
|
||||
@@ -135,7 +135,7 @@ m_genint_clear(m_genint_t s)
|
||||
}
|
||||
|
||||
/* Return the maximum integer that the generator will provide */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_genint_size(m_genint_t s)
|
||||
{
|
||||
M_GEN1NT_CONTRACT(s);
|
||||
@@ -144,7 +144,7 @@ m_genint_size(m_genint_t s)
|
||||
|
||||
/* Get an unique integer from the integer generator.
|
||||
* NOTE: For a typical case, the amortized cost is one CAS per pop. */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_genint_pop(m_genint_t s)
|
||||
{
|
||||
M_GEN1NT_CONTRACT(s);
|
||||
@@ -204,7 +204,7 @@ m_genint_pop(m_genint_t s)
|
||||
|
||||
/* Restore a used integer in the integer generator.
|
||||
* NOTE: For a typical case, the amortized cost is one CAS per pop */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_genint_push(m_genint_t s, unsigned int n)
|
||||
{
|
||||
M_GEN1NT_CONTRACT(s);
|
||||
|
||||
+38
-40
@@ -26,7 +26,7 @@
|
||||
#define MSTARLIB_I_LIST_H
|
||||
|
||||
#include "m-core.h"
|
||||
#include "m-list.h" // For M_L1ST_DEF_ITBASE
|
||||
#include "m-list.h" // For M_L1ST_ITBASE_DEF
|
||||
|
||||
/* Interface to add to a structure to enable intrusive doubly-linked support.
|
||||
name: name of the intrusive list.
|
||||
@@ -120,8 +120,6 @@ typedef struct m_il1st_head_s {
|
||||
M_IF_METHOD(NEW, oplist)(IT_INSERT(M_F(name,_insert)),), \
|
||||
OPLIST(oplist), \
|
||||
SPLICE_BACK(M_F(name,_splice_back)) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -169,7 +167,7 @@ typedef struct m_il1st_head_s {
|
||||
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
|
||||
M_IL1ST_DEF_CORE(name, type, oplist, list_t, it_t) \
|
||||
/* Used of internal macro from m-list */ \
|
||||
M_L1ST_DEF_ITBASE(M_EXPAND_FUNC_INLINE, name, type, oplist, list_t, it_t)
|
||||
M_L1ST_ITBASE_DEF(name, type, oplist, list_t, it_t)
|
||||
|
||||
/* Define the type of an intrusive list */
|
||||
#define M_IL1ST_DEF_TYPE(name, type, oplist, list_t, it_t) \
|
||||
@@ -200,7 +198,7 @@ typedef struct m_il1st_head_s {
|
||||
/* Define core functions for intrusive lists */
|
||||
#define M_IL1ST_DEF_CORE(name, type, oplist, list_t, it_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(list_t list) \
|
||||
{ \
|
||||
M_ASSERT (list != NULL); \
|
||||
@@ -209,7 +207,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -231,7 +229,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(list_t list) \
|
||||
{ \
|
||||
/* Nothing to do more than clean the list itself */ \
|
||||
@@ -241,7 +239,7 @@ typedef struct m_il1st_head_s {
|
||||
list->name.prev = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(const list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -249,7 +247,7 @@ typedef struct m_il1st_head_s {
|
||||
} \
|
||||
\
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(list_t list, list_t ref) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, ref); \
|
||||
@@ -266,14 +264,14 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(list_t list, list_t ref) \
|
||||
{ \
|
||||
M_F(name, _clear)(list); \
|
||||
M_F(name, _init_move)(list, ref); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(const list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -287,7 +285,7 @@ typedef struct m_il1st_head_s {
|
||||
return s; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_back)(list_t list, type *obj) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -300,7 +298,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_front)(list_t list, type *obj) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -313,7 +311,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push_after)(type *obj_pos, type *obj) \
|
||||
{ \
|
||||
M_ASSERT (obj_pos != NULL && obj != NULL); \
|
||||
@@ -326,7 +324,7 @@ typedef struct m_il1st_head_s {
|
||||
next->prev = &obj->name; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_field)(type *obj) \
|
||||
{ \
|
||||
M_ASSERT (obj != NULL); \
|
||||
@@ -335,7 +333,7 @@ typedef struct m_il1st_head_s {
|
||||
obj->name.prev = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _unlink)(type *obj) \
|
||||
{ \
|
||||
M_ASSERT (obj != NULL); \
|
||||
@@ -350,7 +348,7 @@ typedef struct m_il1st_head_s {
|
||||
obj->name.prev = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _back)(const list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -359,7 +357,7 @@ typedef struct m_il1st_head_s {
|
||||
struct m_il1st_head_s, name); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _front)(const list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -368,7 +366,7 @@ typedef struct m_il1st_head_s {
|
||||
struct m_il1st_head_s, name); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _next_obj)(const list_t list, type const *obj) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -379,7 +377,7 @@ typedef struct m_il1st_head_s {
|
||||
struct m_il1st_head_s, name); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _previous_obj)(const list_t list, type const *obj) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -390,7 +388,7 @@ typedef struct m_il1st_head_s {
|
||||
struct m_il1st_head_s, name); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, const list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -402,7 +400,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t it, const it_t cit) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && cit != NULL); \
|
||||
@@ -413,7 +411,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(it_t it, list_t const list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -425,7 +423,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, list_t const list) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && list != NULL); \
|
||||
@@ -436,7 +434,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -444,7 +442,7 @@ typedef struct m_il1st_head_s {
|
||||
return it->current == it->head; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -452,7 +450,7 @@ typedef struct m_il1st_head_s {
|
||||
return it->next == it->head || it->current == it->head; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -467,7 +465,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -482,7 +480,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_NODE_CONTRACT(it->current); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const it_t it1, const it_t it2 ) \
|
||||
{ \
|
||||
M_ASSERT (it1 != NULL && it2 != NULL); \
|
||||
@@ -490,7 +488,7 @@ typedef struct m_il1st_head_s {
|
||||
return it1->head == it2->head && it1->current == it2->current; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->current != NULL); \
|
||||
@@ -503,14 +501,14 @@ typedef struct m_il1st_head_s {
|
||||
struct m_il1st_head_s, name); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(const it_t it) \
|
||||
{ \
|
||||
type *ptr = M_F(name, _ref)(it); \
|
||||
return M_CONST_CAST(type, ptr); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _remove)(list_t list, it_t it) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -525,7 +523,7 @@ typedef struct m_il1st_head_s {
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD2(NEW, INIT_SET, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _insert)(list_t list, it_t it, type x) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -544,7 +542,7 @@ typedef struct m_il1st_head_s {
|
||||
} \
|
||||
, /* NEW & INIT_SET not defined */) \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _pop_back)(list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -555,7 +553,7 @@ typedef struct m_il1st_head_s {
|
||||
return obj; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _pop_front)(list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
@@ -566,7 +564,7 @@ typedef struct m_il1st_head_s {
|
||||
return obj; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice)(list_t list1, list_t list2) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list1); \
|
||||
@@ -583,7 +581,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, list2); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice_back)(list_t nv, list_t ov, it_t it) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, nv); \
|
||||
@@ -599,7 +597,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, ov); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _splice_at)(list_t nlist, it_t npos, \
|
||||
list_t olist, it_t opos) \
|
||||
{ \
|
||||
@@ -629,7 +627,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, olist); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(list_t d, list_t e) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, d); \
|
||||
@@ -652,7 +650,7 @@ typedef struct m_il1st_head_s {
|
||||
M_IL1ST_CONTRACT(name, e); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reverse)(list_t list) \
|
||||
{ \
|
||||
M_IL1ST_CONTRACT(name, list); \
|
||||
|
||||
+10
-13
@@ -55,13 +55,13 @@ M_BEGIN_PROTECTED_CODE
|
||||
ATOMIC_VAR_INIT(0)
|
||||
|
||||
|
||||
/* Define the intrusive shared pointer type and its static inline functions.
|
||||
/* Define the intrusive shared pointer type and its M_INLINE functions.
|
||||
USAGE: ISHARED_PTR_DEF(name, type, [, oplist]) */
|
||||
#define M_ISHARED_PTR_DEF(name, ...) \
|
||||
M_ISHARED_PTR_DEF_AS(name, M_F(name,_t), __VA_ARGS__)
|
||||
|
||||
|
||||
/* Define the intrusive shared pointer type and its static inline functions
|
||||
/* Define the intrusive shared pointer type and its M_INLINE functions
|
||||
as the name name_t
|
||||
USAGE: ISHARED_PTR_DEF_AS(name, name_t, type, [, oplist]) */
|
||||
#define M_ISHARED_PTR_DEF_AS(name, name_t, ...) \
|
||||
@@ -98,9 +98,6 @@ M_BEGIN_PROTECTED_CODE
|
||||
TYPE(M_F(name, _ct)), \
|
||||
OPLIST(oplist), \
|
||||
SUBTYPE(M_F(name, _subtype_ct)) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -135,7 +132,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
/* Define the core functions */
|
||||
#define M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, shared_t) \
|
||||
\
|
||||
static inline shared_t \
|
||||
M_INLINE shared_t \
|
||||
M_F(name, _init)(type *ptr) \
|
||||
{ \
|
||||
/* Initialize the type referenced by the pointer */ \
|
||||
@@ -145,7 +142,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
return ptr; \
|
||||
} \
|
||||
\
|
||||
static inline shared_t \
|
||||
M_INLINE shared_t \
|
||||
M_F(name, _init_set)(shared_t shared) \
|
||||
{ \
|
||||
if (M_LIKELY (shared != NULL)) { \
|
||||
@@ -159,7 +156,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
M_IF_DISABLED_METHOD(NEW, oplist) \
|
||||
( \
|
||||
/* This function is only for static object */ \
|
||||
static inline shared_t \
|
||||
M_INLINE shared_t \
|
||||
M_F(name, _init_once)(type *shared) \
|
||||
{ \
|
||||
if (M_LIKELY (shared != NULL)) { \
|
||||
@@ -190,7 +187,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
, \
|
||||
/* This function is only for dynamic object */ \
|
||||
static inline shared_t \
|
||||
M_INLINE shared_t \
|
||||
M_F(name, _init_new)(void) \
|
||||
{ \
|
||||
type *ptr = M_CALL_NEW(oplist, type); \
|
||||
@@ -205,7 +202,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
/* End of NEW */) \
|
||||
, /* End of INIT */) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(shared_t shared) \
|
||||
{ \
|
||||
if (shared != NULL) { \
|
||||
@@ -216,7 +213,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear_ptr)(shared_t *shared) \
|
||||
{ \
|
||||
M_ASSERT(shared != NULL); \
|
||||
@@ -224,14 +221,14 @@ M_BEGIN_PROTECTED_CODE
|
||||
*shared = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(shared_t *shared) \
|
||||
{ \
|
||||
M_F(name, _clear)(*shared); \
|
||||
*shared = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(shared_t *ptr, shared_t shared) \
|
||||
{ \
|
||||
M_ASSERT (ptr != NULL); \
|
||||
|
||||
+4
-4
@@ -109,7 +109,7 @@
|
||||
/* Define the core functions of the mempool */
|
||||
#define M_M3MPOOL_DEF_CORE(name, type, name_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_init)(name_t mem) \
|
||||
{ \
|
||||
mem->free_list = NULL; \
|
||||
@@ -123,7 +123,7 @@
|
||||
M_M3MPOOL_CONTRACT(mem, type); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_clear)(name_t mem) \
|
||||
{ \
|
||||
M_M3MPOOL_CONTRACT(mem, type); \
|
||||
@@ -138,7 +138,7 @@
|
||||
mem->current_segment = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name,_alloc)(name_t mem) \
|
||||
{ \
|
||||
M_M3MPOOL_CONTRACT(mem, type); \
|
||||
@@ -173,7 +173,7 @@
|
||||
return &ret->t; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name,_free)(name_t mem, type *ptr) \
|
||||
{ \
|
||||
M_M3MPOOL_CONTRACT(mem, type); \
|
||||
|
||||
+39
-38
@@ -161,95 +161,95 @@
|
||||
/* Define the core functions */
|
||||
#define M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(prioqueue_t p) \
|
||||
{ \
|
||||
M_F(name, _array_init)(p->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(prioqueue_t p, prioqueue_t const o) \
|
||||
{ \
|
||||
M_F(name, _array_init_set)(p->array, o->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(prioqueue_t p, prioqueue_t const o) \
|
||||
{ \
|
||||
M_F(name, _array_set)(p->array, o->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(prioqueue_t p) \
|
||||
{ \
|
||||
M_F(name, _array_clear)(p->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(prioqueue_t p, prioqueue_t o) \
|
||||
{ \
|
||||
M_F(name, _array_init_move)(p->array, o->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(prioqueue_t p, prioqueue_t o) \
|
||||
{ \
|
||||
M_F(name, _array_move)(p->array, o->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(prioqueue_t p, prioqueue_t o) \
|
||||
{ \
|
||||
M_F(name, _array_swap)(p->array, o->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(prioqueue_t p) \
|
||||
{ \
|
||||
M_F(name, _array_reset)(p->array); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _i_parent)(size_t i) \
|
||||
{ \
|
||||
M_ASSERT (i > 0); \
|
||||
return (i - 1) / 2; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _i_lchild)(size_t i) \
|
||||
{ \
|
||||
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
|
||||
return 2*i + 1; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _i_rchild)(size_t i) \
|
||||
{ \
|
||||
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
|
||||
return 2*i + 2; \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
M_INLINE int \
|
||||
M_F(name, _i_cmp)(const prioqueue_t p, size_t i, size_t j) \
|
||||
{ \
|
||||
return M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), \
|
||||
*M_F(name, _array_cget)(p->array, j)); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(prioqueue_t const p) \
|
||||
{ \
|
||||
return M_F(name, _array_empty_p)(p->array); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(prioqueue_t const p) \
|
||||
{ \
|
||||
return M_F(name, _array_size)(p->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push)(prioqueue_t p, type const x) \
|
||||
{ \
|
||||
/* Push back the new element at the end of the array */ \
|
||||
@@ -267,13 +267,13 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _front)(prioqueue_t const p) \
|
||||
{ \
|
||||
return M_F(name, _array_cget)(p->array, 0); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _pop)(type *x, prioqueue_t p) \
|
||||
{ \
|
||||
/* Swap the front element with the last element */ \
|
||||
@@ -303,26 +303,27 @@
|
||||
M_IF_METHOD(EQUAL, oplist) \
|
||||
( \
|
||||
/* EQUAL & CMP may be uncorrelated */ \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(prioqueue_t const p, prioqueue_t const q) \
|
||||
{ \
|
||||
return M_F(name, _array_equal_p)(p->array, q->array); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _i_find)(prioqueue_t p, type const x) \
|
||||
{ \
|
||||
size_t size = M_F(name, _array_size)(p->array); \
|
||||
size_t i = 0; \
|
||||
for(i = 0; i < size; i++) { \
|
||||
/* FIXME: Can we use CMP and the partial order to go faster? */ \
|
||||
/* We cannot use CMP and the partial order to go faster \
|
||||
EQUAL & CMP may be uncorrelated */ \
|
||||
if (M_CALL_EQUAL(oplist, *M_F(name, _array_cget)(p->array, i), x)) \
|
||||
break; \
|
||||
} \
|
||||
return i; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _erase)(prioqueue_t p, type const x) \
|
||||
{ \
|
||||
/* First pass: search for an item EQUAL to x */ \
|
||||
@@ -351,7 +352,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _update)(prioqueue_t p, type const xold, type const xnew) \
|
||||
{ \
|
||||
/* NOTE: xold can be the same pointer than xnew */ \
|
||||
@@ -394,62 +395,62 @@
|
||||
#define M_PR1OQUEUE_DEF_IT(name, type, oplist, prioqueue_t, it_t) \
|
||||
\
|
||||
/* Define iterators over the array iterator */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, prioqueue_t const v) \
|
||||
{ \
|
||||
M_F(name, _array_it)(it, v->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(it_t it, prioqueue_t const v) \
|
||||
{ \
|
||||
M_F(name, _array_it_last)(it, v->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, prioqueue_t const v) \
|
||||
{ \
|
||||
M_F(name, _array_it_end)(it, v->array); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t it, const it_t org) \
|
||||
{ \
|
||||
M_F(name, _array_it_set)(it, org); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const it_t it) \
|
||||
{ \
|
||||
return M_F(name, _array_end_p)(it); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _last_p)(const it_t it) \
|
||||
{ \
|
||||
return M_F(name, _array_last_p)(it); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const it_t it1, \
|
||||
const it_t it2) \
|
||||
{ \
|
||||
return M_F(name, _array_it_equal_p)(it1, it2); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_F(name, _array_next)(it); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(it_t it) \
|
||||
{ \
|
||||
M_F(name, _array_previous)(it); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(const it_t it) \
|
||||
{ \
|
||||
return M_F(name, _array_cref)(it); \
|
||||
@@ -458,7 +459,7 @@
|
||||
/* Define the IO functions */
|
||||
#define M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, const prioqueue_t p) \
|
||||
{ \
|
||||
M_F(name, _array_out_str)(file, p->array); \
|
||||
@@ -466,7 +467,7 @@
|
||||
,/* No OUT_STR */) \
|
||||
\
|
||||
M_IF_METHOD(IN_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(prioqueue_t p, FILE *file) \
|
||||
{ \
|
||||
return M_F(name, _array_in_str)(p->array, file); \
|
||||
@@ -474,7 +475,7 @@
|
||||
,/* No IN_STR */) \
|
||||
\
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(string_t str, const prioqueue_t p, bool append) \
|
||||
{ \
|
||||
M_F(name, _array_get_str)(str, p->array, append); \
|
||||
@@ -482,7 +483,7 @@
|
||||
,/* No GET_STR */) \
|
||||
\
|
||||
M_IF_METHOD(PARSE_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(prioqueue_t p, const char str[], const char **endp) \
|
||||
{ \
|
||||
return M_F(name, _array_parse_str)(p->array, str, endp); \
|
||||
@@ -490,7 +491,7 @@
|
||||
,/* No PARSE_STR */) \
|
||||
\
|
||||
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, const prioqueue_t p) \
|
||||
{ \
|
||||
return M_F(name, _array_out_serial)(f, p->array); \
|
||||
@@ -498,7 +499,7 @@
|
||||
,/* No OUT_SERIAL */) \
|
||||
\
|
||||
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(prioqueue_t p, m_serial_read_t f) \
|
||||
{ \
|
||||
return M_F(name, _array_in_serial)(p->array, f); \
|
||||
|
||||
+51
-54
@@ -109,9 +109,6 @@
|
||||
M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),), \
|
||||
M_IF_METHOD(EQUAL, oplist)(EQUAL(M_F(name, _equal_p)),), \
|
||||
M_IF_METHOD(HASH, oplist)(HASH(M_F(name, _hash)),) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
|
||||
@@ -227,28 +224,28 @@ typedef enum {
|
||||
/* Definition of the global variable used to reference this pool */ \
|
||||
M_GET_MEMPOOL_LINKAGE oplist M_F(name, _mempool_t) M_GET_MEMPOOL oplist; \
|
||||
/* Allocator function */ \
|
||||
static inline node_t *M_C3(m_rbtr33_,name,_new)(void) { \
|
||||
M_INLINE node_t *M_C3(m_rbtr33_,name,_new)(void) { \
|
||||
return M_F(name, _mempool_alloc)(M_GET_MEMPOOL oplist); \
|
||||
} \
|
||||
/* Deallocator function */ \
|
||||
static inline void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \
|
||||
M_INLINE void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \
|
||||
M_F(name, _mempool_free)(M_GET_MEMPOOL oplist, ptr); \
|
||||
} \
|
||||
\
|
||||
, /* No mempool allocation */ \
|
||||
/* Classic Allocator function (common case) */ \
|
||||
static inline node_t *M_C3(m_rbtr33_,name,_new)(void) { \
|
||||
M_INLINE node_t *M_C3(m_rbtr33_,name,_new)(void) { \
|
||||
return M_CALL_NEW(oplist, node_t); \
|
||||
} \
|
||||
/* Classic deallocator function (common case) */ \
|
||||
static inline void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \
|
||||
M_INLINE void M_C3(m_rbtr33_,name,_del)(node_t *ptr) { \
|
||||
M_CALL_DEL(oplist, ptr); \
|
||||
} ) \
|
||||
|
||||
/* Define the core functions */
|
||||
#define M_RBTR33_DEF_CORE(name, type, oplist, tree_t, node_t, it_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(tree_t tree) \
|
||||
{ \
|
||||
M_ASSERT (tree != NULL); \
|
||||
@@ -257,7 +254,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(tree); \
|
||||
@@ -302,14 +299,14 @@ typedef enum {
|
||||
tree->size = 0; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(tree_t tree) \
|
||||
{ \
|
||||
/* Nothing more than clean the tree as everything is cleared */ \
|
||||
M_F(name, _reset)(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _push)(tree_t tree, type const data) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(tree); \
|
||||
@@ -435,7 +432,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(const tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -443,7 +440,7 @@ typedef enum {
|
||||
} \
|
||||
\
|
||||
/* Set the iterator to the first (child=0) or last (child=1) element */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_rbtr33_,name,_it)(it_t it, const tree_t tree, int child) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -465,19 +462,19 @@ typedef enum {
|
||||
it->cpt = cpt; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, const tree_t tree) \
|
||||
{ \
|
||||
M_C3(m_rbtr33_,name,_it)(it, tree, 0); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_last)(it_t it, const tree_t tree) \
|
||||
{ \
|
||||
M_C3(m_rbtr33_,name,_it)(it, tree, 1); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_end)(it_t it, const tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -486,14 +483,14 @@ typedef enum {
|
||||
it->cpt = 0; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t it, const it_t ref) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && ref != NULL); \
|
||||
*it = *ref; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -501,7 +498,7 @@ typedef enum {
|
||||
} \
|
||||
\
|
||||
/* Go to the next (child = 0)or previous element (child = 1) */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_rbtr33_,name,_next)(it_t it, int child) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -533,19 +530,19 @@ typedef enum {
|
||||
it->cpt = cpt; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t it) \
|
||||
{ \
|
||||
M_C3(m_rbtr33_,name,_next)(it, 0); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _previous)(it_t it) \
|
||||
{ \
|
||||
M_C3(m_rbtr33_,name,_next)(it, 1); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(const it_t it) \
|
||||
{ \
|
||||
M_ASSERT(it != NULL); \
|
||||
@@ -555,13 +552,13 @@ typedef enum {
|
||||
return &(it->stack[it->cpt-1]->data); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(const it_t it) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_F(name, _ref)(it)); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(const it_t it1, const it_t it2) \
|
||||
{ \
|
||||
M_ASSERT(it1 != NULL && it2 != NULL); \
|
||||
@@ -572,7 +569,7 @@ typedef enum {
|
||||
&& (it1->cpt == 0 || it1->stack[it1->cpt-1] == it2->stack[it2->cpt-1]); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_from)(it_t it, const tree_t tree, type const data) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -601,7 +598,7 @@ typedef enum {
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_until_p)(it_t it, type const data) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -612,7 +609,7 @@ typedef enum {
|
||||
return (cmp >= 0); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_while_p)(it_t it, type const data) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
@@ -623,7 +620,7 @@ typedef enum {
|
||||
return (cmp <= 0); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _min)(const tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -636,7 +633,7 @@ typedef enum {
|
||||
return &n->data; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _max)(const tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -649,19 +646,19 @@ typedef enum {
|
||||
return &n->data; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cmin)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_F(name, _min)(tree)); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cmax)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_F(name, _max)(tree)); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _get)(const tree_t tree, type const data) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -680,14 +677,14 @@ typedef enum {
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cget)(const tree_t tree, type const data) \
|
||||
{ \
|
||||
return M_CONST_CAST(type, M_F(name, _get)(tree, data)); \
|
||||
} \
|
||||
\
|
||||
/* Create a copy of the given node (recursively) */ \
|
||||
static inline node_t * \
|
||||
M_INLINE node_t * \
|
||||
M_C3(m_rbtr33_,name,_copy_node)(const node_t *o) \
|
||||
{ \
|
||||
if (o == NULL) return NULL; \
|
||||
@@ -703,7 +700,7 @@ typedef enum {
|
||||
return n; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(tree_t tree, const tree_t ref) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (ref); \
|
||||
@@ -714,7 +711,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(tree_t tree, const tree_t ref) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -724,7 +721,7 @@ typedef enum {
|
||||
M_F(name,_init_set)(tree, ref); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(tree_t tree, tree_t ref) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (ref); \
|
||||
@@ -736,7 +733,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(tree_t tree, tree_t ref) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -747,7 +744,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(tree_t tree1, tree_t tree2) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree1); \
|
||||
@@ -758,7 +755,7 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT (tree2); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(const tree_t tree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -766,19 +763,19 @@ typedef enum {
|
||||
} \
|
||||
\
|
||||
/* Take care of the case n == NULL too */ \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C3(m_rbtr33_,name,_black_p)(const node_t *n) \
|
||||
{ \
|
||||
return (n == NULL) ? true : M_RBTR33_IS_BLACK(n); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_rbtr33_,name,_set_black)(node_t *n) \
|
||||
{ \
|
||||
if (n != NULL) M_RBTR33_SET_BLACK(n); \
|
||||
} \
|
||||
\
|
||||
static inline node_t * \
|
||||
M_INLINE node_t * \
|
||||
M_C3(m_rbtr33_,name,_rotate)(node_t *pp, node_t *ppp, const bool right) \
|
||||
{ \
|
||||
M_ASSERT (pp != NULL && ppp != NULL); \
|
||||
@@ -795,7 +792,7 @@ typedef enum {
|
||||
\
|
||||
M_IF_DEBUG( \
|
||||
/* Compute the depth of a node */ \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_C3(m_rbtr33_,name,_compute_depth)(const node_t *n) \
|
||||
{ \
|
||||
if (n == NULL) return 1; \
|
||||
@@ -804,7 +801,7 @@ typedef enum {
|
||||
} \
|
||||
) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _pop_at)(type *data_ptr, tree_t tree, type const key) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT (tree); \
|
||||
@@ -964,7 +961,7 @@ typedef enum {
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline void M_F(name,_remove)(tree_t t, it_t it) \
|
||||
M_INLINE void M_F(name,_remove)(tree_t t, it_t it) \
|
||||
{ \
|
||||
/* Not optimum: another search in the tree is performed */ \
|
||||
type data; \
|
||||
@@ -979,7 +976,7 @@ typedef enum {
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool M_F(name,_equal_p)(const tree_t t1, const tree_t t2) { \
|
||||
M_INLINE bool M_F(name,_equal_p)(const tree_t t1, const tree_t t2) { \
|
||||
M_RBTR33_CONTRACT(t1); \
|
||||
M_RBTR33_CONTRACT(t2); \
|
||||
if (t1->size != t2->size) return false; \
|
||||
@@ -1006,7 +1003,7 @@ typedef enum {
|
||||
, /* NO EQUAL METHOD */ ) \
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t M_F(name,_hash)(const tree_t t1) { \
|
||||
M_INLINE size_t M_F(name,_hash)(const tree_t t1) { \
|
||||
M_RBTR33_CONTRACT(t1); \
|
||||
M_HASH_DECL(hash); \
|
||||
/* NOTE: We can't compute the hash directly for the same reason \
|
||||
@@ -1025,7 +1022,7 @@ typedef enum {
|
||||
/* Define the I/O functions */
|
||||
#define M_RBTR33_DEF_IO(name, type, oplist, tree_t, node_t, it_t) \
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void M_F(name, _get_str)(m_string_t str, \
|
||||
M_INLINE void M_F(name, _get_str)(m_string_t str, \
|
||||
tree_t const t1, bool append) { \
|
||||
M_RBTR33_CONTRACT(t1); \
|
||||
M_ASSERT(str != NULL); \
|
||||
@@ -1047,7 +1044,7 @@ typedef enum {
|
||||
, /* NO GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *file, tree_t const rbtree) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(rbtree); \
|
||||
@@ -1069,7 +1066,7 @@ typedef enum {
|
||||
, /* no out_str */ ) \
|
||||
\
|
||||
M_IF_METHOD(PARSE_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(tree_t rbtree, const char str[], const char **endp) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(rbtree); \
|
||||
@@ -1100,7 +1097,7 @@ typedef enum {
|
||||
, /* no parse_str */ ) \
|
||||
\
|
||||
M_IF_METHOD(IN_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(tree_t rbtree, FILE *file) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(rbtree); \
|
||||
@@ -1126,7 +1123,7 @@ typedef enum {
|
||||
, /* no in_str */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, tree_t const t1) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(t1); \
|
||||
@@ -1152,7 +1149,7 @@ typedef enum {
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
\
|
||||
M_IF_METHOD(IN_SERIAL, oplist)( \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(tree_t t1, m_serial_read_t f) \
|
||||
{ \
|
||||
M_RBTR33_CONTRACT(t1); \
|
||||
|
||||
+66
-120
@@ -41,7 +41,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
* Write size_t in the stream in a compact form to reduce consumption
|
||||
* (and I/O bandwidth)
|
||||
*/
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_ser1al_bin_write_size(FILE *f, const size_t size)
|
||||
{
|
||||
bool b;
|
||||
@@ -88,7 +88,7 @@ m_ser1al_bin_write_size(FILE *f, const size_t size)
|
||||
* Read size_t in the stream from a compact form to reduce consumption
|
||||
* (and I/O bandwidth)
|
||||
*/
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_ser1al_bin_read_size(FILE *f, size_t *size)
|
||||
{
|
||||
int c;
|
||||
@@ -111,7 +111,7 @@ m_ser1al_bin_read_size(FILE *f, size_t *size)
|
||||
|
||||
/* Write the boolean 'data' into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_boolean(m_serial_write_t serial, const bool data)
|
||||
{
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
@@ -121,69 +121,54 @@ m_ser1al_bin_write_boolean(m_serial_write_t serial, const bool data)
|
||||
|
||||
/* Write the integer 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_integer(m_serial_write_t serial,const long long data, const size_t size_of_type)
|
||||
{
|
||||
int8_t i8;
|
||||
int16_t i16;
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
size_t n;
|
||||
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
switch (size_of_type) {
|
||||
case 1:
|
||||
i8 = (int8_t) data;
|
||||
if (size_of_type == 1) {
|
||||
int8_t i8 = (int8_t) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &i8), sizeof i8, 1, f);
|
||||
break;
|
||||
case 2:
|
||||
i16 = (int16_t) data;
|
||||
} else if (size_of_type == 2) {
|
||||
int16_t i16 = (int16_t) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &i16), sizeof i16, 1, f);
|
||||
break;
|
||||
case 4:
|
||||
i32 = (int32_t) data;
|
||||
} else if (size_of_type == 4) {
|
||||
int32_t i32 = (int32_t) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &i32), sizeof i32, 1, f);
|
||||
break;
|
||||
case 8:
|
||||
i64 = (int64_t) data;
|
||||
} else {
|
||||
M_ASSERT(size_of_type == 8);
|
||||
int64_t i64 = (int64_t) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &i64), sizeof i64, 1, f);
|
||||
break;
|
||||
default:
|
||||
M_ASSERT_INIT(false, "an integer of suitable size (8/16/32/64)");
|
||||
break;
|
||||
}
|
||||
return n == 1 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
}
|
||||
|
||||
/* Write the float 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_float(m_serial_write_t serial, const long double data, const size_t size_of_type)
|
||||
{
|
||||
float f1;
|
||||
double f2;
|
||||
long double f3;
|
||||
size_t n;
|
||||
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
if (size_of_type == sizeof f1) {
|
||||
f1 = (float) data;
|
||||
if (size_of_type == sizeof (float) ) {
|
||||
float f1 = (float) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &f1), sizeof f1, 1, f);
|
||||
} else if (size_of_type == sizeof f2) {
|
||||
f2 = (double) data;
|
||||
} else if (size_of_type == sizeof (double) ) {
|
||||
double f2 = (double) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &f2), sizeof f2, 1, f);
|
||||
} else if (size_of_type == sizeof f3) {
|
||||
f3 = (long double) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &f3), sizeof f3, 1, f);
|
||||
} else {
|
||||
M_ASSERT_INIT(false, "a float of suitable size");
|
||||
M_ASSERT(size_of_type == sizeof (long double) );
|
||||
long double f3 = (long double) data;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &f3), sizeof f3, 1, f);
|
||||
}
|
||||
return n == 1 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
}
|
||||
|
||||
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_string(m_serial_write_t serial, const char data[], size_t length)
|
||||
{
|
||||
M_ASSERT_SLOW(length == strlen(data) );
|
||||
@@ -203,50 +188,39 @@ m_ser1al_bin_write_string(m_serial_write_t serial, const char data[], size_t len
|
||||
Initialize 'local' so that it can be used to serialize the array
|
||||
(local is an unique serialization object of the array).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_array_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; //Unused
|
||||
if (number_of_elements == (size_t)-1) return M_SERIAL_FAIL_RETRY;
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
size_t n = fwrite (M_ASSIGN_CAST(const void*, &number_of_elements), sizeof number_of_elements, 1, f);
|
||||
local->data[0].b = (number_of_elements == 0);
|
||||
return n == 1 ? M_SERIAL_OK_CONTINUE : m_core_serial_fail();
|
||||
}
|
||||
|
||||
/* Write an array separator between elements of an array into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_array_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
// Need separator if we don't know the real size
|
||||
if (local->data[0].b) {
|
||||
size_t n = 0xABCDEF;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &n), sizeof n, 1, f);
|
||||
return n == 1 ? M_SERIAL_OK_CONTINUE : m_core_serial_fail();
|
||||
} else {
|
||||
return M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
(void) local; // Unused
|
||||
(void) serial; // Unused
|
||||
return M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
|
||||
/* End the writing of an array into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_array_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
// Need mark if we don't know the real size
|
||||
if (local->data[0].b) {
|
||||
size_t n = 0x12345678;
|
||||
n = fwrite (M_ASSIGN_CAST(const void*, &n), sizeof n, 1, f);
|
||||
return n == 1 ? M_SERIAL_OK_CONTINUE : m_core_serial_fail();
|
||||
} else {
|
||||
return M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
(void) local; // Unused
|
||||
(void) serial; // Unused
|
||||
return M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
|
||||
/* Write a value separator between element of the same pair of a map into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -258,7 +232,7 @@ m_ser1al_bin_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
Initialize 'local' so that it can serial the tuple
|
||||
(local is an unique serialization object of the tuple).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -268,7 +242,7 @@ m_ser1al_bin_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
|
||||
/* Start writing the field named field_name[index] of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -281,7 +255,7 @@ m_ser1al_bin_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, con
|
||||
|
||||
/* End the write of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -294,7 +268,7 @@ m_ser1al_bin_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise
|
||||
Otherwise, the field 'field_name[index]' will be filled.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_variant_start(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) field_name;
|
||||
@@ -307,7 +281,7 @@ m_ser1al_bin_write_variant_start(m_serial_local_t local, m_serial_write_t serial
|
||||
|
||||
/* End Writing a variant into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_write_variant_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -335,13 +309,13 @@ static const m_serial_write_interface_t m_ser1al_bin_write_interface = {
|
||||
m_ser1al_bin_write_variant_end
|
||||
};
|
||||
|
||||
static inline void m_serial_bin_write_init(m_serial_write_t serial, FILE *f)
|
||||
M_INLINE void m_serial_bin_write_init(m_serial_write_t serial, FILE *f)
|
||||
{
|
||||
serial->m_interface = &m_ser1al_bin_write_interface;
|
||||
serial->data[0].p = M_ASSIGN_CAST(void*, f);
|
||||
}
|
||||
|
||||
static inline void m_serial_bin_write_clear(m_serial_write_t serial)
|
||||
M_INLINE void m_serial_bin_write_clear(m_serial_write_t serial)
|
||||
{
|
||||
(void) serial; // Nothing to do
|
||||
}
|
||||
@@ -363,7 +337,7 @@ typedef m_serial_write_t m_serial_bin_write_t;
|
||||
/* Read from the stream 'serial' a boolean.
|
||||
Set '*b' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_boolean(m_serial_read_t serial, bool *b){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
size_t n = fread (M_ASSIGN_CAST(void*, b), sizeof (bool), 1, f);
|
||||
@@ -373,7 +347,7 @@ m_ser1al_bin_read_boolean(m_serial_read_t serial, bool *b){
|
||||
/* Read from the stream 'serial' an integer that can be represented with 'size_of_type' bytes.
|
||||
Set '*i' with the integer value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_integer(m_serial_read_t serial, long long *i, const size_t size_of_type){
|
||||
int8_t i8;
|
||||
int16_t i16;
|
||||
@@ -381,26 +355,19 @@ m_ser1al_bin_read_integer(m_serial_read_t serial, long long *i, const size_t siz
|
||||
int64_t i64;
|
||||
size_t n;
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
switch (size_of_type) {
|
||||
case 1:
|
||||
if (size_of_type == 1) {
|
||||
n = fread (M_ASSIGN_CAST(void*, &i8), sizeof i8, 1, f);
|
||||
*i = i8;
|
||||
break;
|
||||
case 2:
|
||||
} else if (size_of_type == 2) {
|
||||
n = fread (M_ASSIGN_CAST(void*, &i16), sizeof i16, 1, f);
|
||||
*i = i16;
|
||||
break;
|
||||
case 4:
|
||||
} else if (size_of_type == 4) {
|
||||
n = fread (M_ASSIGN_CAST(void*, &i32), sizeof i32, 1, f);
|
||||
*i = i32;
|
||||
break;
|
||||
case 8:
|
||||
} else {
|
||||
M_ASSERT(size_of_type == 8);
|
||||
n = fread (M_ASSIGN_CAST(void*, &i64), sizeof i64, 1, f);
|
||||
*i = i64;
|
||||
break;
|
||||
default:
|
||||
M_ASSERT_INIT(false, "an integer of suitable size");
|
||||
break;
|
||||
}
|
||||
return n == 1 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
}
|
||||
@@ -408,7 +375,7 @@ m_ser1al_bin_read_integer(m_serial_read_t serial, long long *i, const size_t siz
|
||||
/* Read from the stream 'serial' a float that can be represented with 'size_of_type' bytes.
|
||||
Set '*r' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_float(m_serial_read_t serial, long double *r, const size_t size_of_type){
|
||||
float f1;
|
||||
double f2;
|
||||
@@ -421,11 +388,10 @@ m_ser1al_bin_read_float(m_serial_read_t serial, long double *r, const size_t siz
|
||||
} else if (size_of_type == sizeof f2) {
|
||||
n = fread (M_ASSIGN_CAST(void*, &f2), sizeof f2, 1, f);
|
||||
*r = f2;
|
||||
} else if (size_of_type == sizeof f3) {
|
||||
} else {
|
||||
M_ASSERT(size_of_type == sizeof f3);
|
||||
n = fread (M_ASSIGN_CAST(void*, &f3), sizeof f3, 1, f);
|
||||
*r = f3;
|
||||
} else {
|
||||
M_ASSERT_INIT(false, "a float of suitable size");
|
||||
}
|
||||
return n == 1 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
}
|
||||
@@ -433,7 +399,7 @@ m_ser1al_bin_read_float(m_serial_read_t serial, long double *r, const size_t siz
|
||||
/* Read from the stream 'serial' a string.
|
||||
Set 's' with the string if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_string(m_serial_read_t serial, struct string_s *s){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
M_ASSERT(f != NULL && s != NULL);
|
||||
@@ -458,53 +424,33 @@ m_ser1al_bin_read_string(m_serial_read_t serial, struct string_s *s){
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends (the array is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_array_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
size_t n = fread (M_ASSIGN_CAST(void*, num), sizeof *num, 1, f);
|
||||
if (n != 1)
|
||||
return m_core_serial_fail();
|
||||
local->data[0].b = (*num == 0);
|
||||
local->data[1].s = *num;
|
||||
if (local->data[0].b) {
|
||||
// Size not know ==> use of marker in the stream.
|
||||
size_t p;
|
||||
n = fread (M_ASSIGN_CAST(void*, &p), sizeof p, 1, f);
|
||||
if (n != 1)
|
||||
return m_core_serial_fail();
|
||||
return p == 0xABCDEF ? M_SERIAL_OK_CONTINUE : p == 0x12345678 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
}
|
||||
return M_SERIAL_OK_CONTINUE;
|
||||
return (n != 1) ? m_core_serial_fail() : (local->data[1].s == 0) ? M_SERIAL_OK_DONE : M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
|
||||
/* Continue reading from the stream 'serial' an array.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_array_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
if (local->data[0].b) {
|
||||
// Size not know ==> use of marker in the stream.
|
||||
size_t p, n;
|
||||
n = fread (M_ASSIGN_CAST(void*, &p), sizeof p, 1, f);
|
||||
if (n != 1)
|
||||
return m_core_serial_fail();
|
||||
return p == 0xABCDEF ? M_SERIAL_OK_CONTINUE : p == 0x12345678 ? M_SERIAL_OK_DONE : m_core_serial_fail();
|
||||
} else {
|
||||
M_ASSERT(local->data[1].s > 0);
|
||||
local->data[1].s --;
|
||||
return local->data[1].s == 0 ? M_SERIAL_OK_DONE : M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
(void) serial; // Unused
|
||||
M_ASSERT(local->data[1].s > 0);
|
||||
local->data[1].s --;
|
||||
return local->data[1].s == 0 ? M_SERIAL_OK_DONE : M_SERIAL_OK_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
/* Continue reading from the stream 'serial' the value separator
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -515,7 +461,7 @@ m_ser1al_bin_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
/* Start reading a tuple from the stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) serial;
|
||||
@@ -529,7 +475,7 @@ m_ser1al_bin_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the tuple ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, const char *const field_name [], const int max, int *id)
|
||||
{
|
||||
(void) serial;
|
||||
@@ -546,7 +492,7 @@ m_ser1al_bin_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, const
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the variant continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends(variant is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_variant_start(m_serial_local_t local, m_serial_read_t serial, const char *const field_name[], const int max, int*id)
|
||||
{
|
||||
(void) field_name;
|
||||
@@ -560,7 +506,7 @@ m_ser1al_bin_read_variant_start(m_serial_local_t local, m_serial_read_t serial,
|
||||
/* End reading a variant from the stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_bin_read_variant_end(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -584,13 +530,13 @@ static const m_serial_read_interface_t m_ser1al_bin_read_interface = {
|
||||
m_ser1al_bin_read_variant_end
|
||||
};
|
||||
|
||||
static inline void m_serial_bin_read_init(m_serial_read_t serial, FILE *f)
|
||||
M_INLINE void m_serial_bin_read_init(m_serial_read_t serial, FILE *f)
|
||||
{
|
||||
serial->m_interface = &m_ser1al_bin_read_interface;
|
||||
serial->data[0].p = M_ASSIGN_CAST(void*, f);
|
||||
}
|
||||
|
||||
static inline void m_serial_bin_read_clear(m_serial_read_t serial)
|
||||
M_INLINE void m_serial_bin_read_clear(m_serial_read_t serial)
|
||||
{
|
||||
(void) serial; // Nothing to do
|
||||
}
|
||||
|
||||
+71
-71
@@ -36,7 +36,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
|
||||
/* Write the boolean 'data' into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_boolean(m_serial_write_t serial, const bool data)
|
||||
{
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
@@ -46,7 +46,7 @@ m_ser1al_json_write_boolean(m_serial_write_t serial, const bool data)
|
||||
|
||||
/* Write the integer 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_integer(m_serial_write_t serial,const long long data, const size_t size_of_type)
|
||||
{
|
||||
(void) size_of_type; // Ignored
|
||||
@@ -57,7 +57,7 @@ m_ser1al_json_write_integer(m_serial_write_t serial,const long long data, const
|
||||
|
||||
/* Write the float 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_float(m_serial_write_t serial, const long double data, const size_t size_of_type)
|
||||
{
|
||||
(void) size_of_type; // Ignored
|
||||
@@ -68,7 +68,7 @@ m_ser1al_json_write_float(m_serial_write_t serial, const long double data, const
|
||||
|
||||
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_string(m_serial_write_t serial, const char data[], size_t length)
|
||||
{
|
||||
M_ASSERT_SLOW(length == strlen(data) );
|
||||
@@ -81,7 +81,7 @@ m_ser1al_json_write_string(m_serial_write_t serial, const char data[], size_t le
|
||||
v2->u.heap.alloc = length + 1;
|
||||
v2->ptr = (char*)ptr;
|
||||
m_string_out_str(f, v2);
|
||||
return M_SERIAL_OK_DONE;
|
||||
return M_UNLIKELY(ferror(f)) ? m_core_serial_fail() : M_SERIAL_OK_DONE;
|
||||
}
|
||||
|
||||
/* Start writing an array of 'number_of_elements' objects into the serial stream 'serial'.
|
||||
@@ -90,7 +90,7 @@ m_ser1al_json_write_string(m_serial_write_t serial, const char data[], size_t le
|
||||
Initialize 'local' so that it can be used to serialize the array
|
||||
(local is an unique serialization object of the array).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_array_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -102,7 +102,7 @@ m_ser1al_json_write_array_start(m_serial_local_t local, m_serial_write_t serial,
|
||||
|
||||
/* Write an array separator between elements of an array into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_array_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -113,7 +113,7 @@ m_ser1al_json_write_array_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
|
||||
/* End the writing of an array into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_array_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -128,7 +128,7 @@ m_ser1al_json_write_array_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
Initialize 'local' so that it can be used to serialize the map
|
||||
(local is an unique serialization object of the map).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_map_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -140,7 +140,7 @@ m_ser1al_json_write_map_start(m_serial_local_t local, m_serial_write_t serial, c
|
||||
|
||||
/* Write a value separator between element of the same pair of a map into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -151,7 +151,7 @@ m_ser1al_json_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
|
||||
/* Write a map separator between elements of a map into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_map_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -162,7 +162,7 @@ m_ser1al_json_write_map_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
|
||||
/* End the writing of a map into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_map_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -175,7 +175,7 @@ m_ser1al_json_write_map_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
Initialize 'local' so that it can serial the tuple
|
||||
(local is an unique serialization object of the tuple).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -186,7 +186,7 @@ m_ser1al_json_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
|
||||
/* Start writing the field named field_name[index] of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -198,7 +198,7 @@ m_ser1al_json_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, co
|
||||
|
||||
/* End the write of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -212,7 +212,7 @@ m_ser1al_json_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise
|
||||
Otherwise, the field 'field_name[index]' will be filled.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_variant_start(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -231,7 +231,7 @@ m_ser1al_json_write_variant_start(m_serial_local_t local, m_serial_write_t seria
|
||||
|
||||
/* End Writing a variant into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_write_variant_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -262,14 +262,14 @@ static const m_serial_write_interface_t m_ser1al_json_write_interface = {
|
||||
};
|
||||
|
||||
/* Initialize the JSON serial object for writing any object to JSON format in the given FILE */
|
||||
static inline void m_serial_json_write_init(m_serial_write_t serial, FILE *f)
|
||||
M_INLINE void m_serial_json_write_init(m_serial_write_t serial, FILE *f)
|
||||
{
|
||||
serial->m_interface = &m_ser1al_json_write_interface;
|
||||
serial->data[0].p = M_ASSIGN_CAST(void*, f);
|
||||
}
|
||||
|
||||
/* CLear the JSON serial object for writing*/
|
||||
static inline void m_serial_json_write_clear(m_serial_write_t serial)
|
||||
M_INLINE void m_serial_json_write_clear(m_serial_write_t serial)
|
||||
{
|
||||
(void) serial; // Nothing to do
|
||||
}
|
||||
@@ -288,7 +288,7 @@ typedef m_serial_write_t m_serial_json_write_t;
|
||||
/********************************************************************************/
|
||||
|
||||
/* Helper function to skip a space */
|
||||
static inline int
|
||||
M_INLINE int
|
||||
m_ser1al_json_read_skip (FILE *f)
|
||||
{
|
||||
int c;
|
||||
@@ -302,7 +302,7 @@ m_ser1al_json_read_skip (FILE *f)
|
||||
/* Read from the stream 'serial' a boolean.
|
||||
Set '*b' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_boolean(m_serial_read_t serial, bool *b){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int c = m_ser1al_json_read_skip(f);
|
||||
@@ -334,7 +334,7 @@ m_ser1al_json_read_boolean(m_serial_read_t serial, bool *b){
|
||||
/* Read from the stream 'serial' an integer that can be represented with 'size_of_type' bytes.
|
||||
Set '*i' with the integer value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_integer(m_serial_read_t serial, long long *i, const size_t size_of_type){
|
||||
(void) size_of_type; // Ignored
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
@@ -344,7 +344,7 @@ m_ser1al_json_read_integer(m_serial_read_t serial, long long *i, const size_t si
|
||||
/* Read from the stream 'serial' a float that can be represented with 'size_of_type' bytes.
|
||||
Set '*r' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_float(m_serial_read_t serial, long double *r, const size_t size_of_type){
|
||||
(void) size_of_type; // Ignored
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
@@ -354,7 +354,7 @@ m_ser1al_json_read_float(m_serial_read_t serial, long double *r, const size_t si
|
||||
/* Read from the stream 'serial' a string.
|
||||
Set 's' with the string if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_string(m_serial_read_t serial, struct m_string_s *s){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int n = m_core_fscanf(f, " "); // Skip any leading spaces.
|
||||
@@ -369,7 +369,7 @@ m_ser1al_json_read_string(m_serial_read_t serial, struct m_string_s *s){
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends (the array is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_array_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -387,7 +387,7 @@ m_ser1al_json_read_array_start(m_serial_local_t local, m_serial_read_t serial, s
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_array_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -405,7 +405,7 @@ m_ser1al_json_read_array_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the map ends (the map is empty),
|
||||
m_core_serial_fail() otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_map_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -422,7 +422,7 @@ m_ser1al_json_read_map_start(m_serial_local_t local, m_serial_read_t serial, siz
|
||||
/* Continue reading from the stream 'serial' the value separator
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -437,7 +437,7 @@ m_ser1al_json_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the map ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_map_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -451,7 +451,7 @@ m_ser1al_json_read_map_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
/* Start reading a tuple from the stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -468,7 +468,7 @@ m_ser1al_json_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the tuple ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, const char *const field_name [], const int max, int *id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -507,7 +507,7 @@ m_ser1al_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, cons
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the variant continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends(variant is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_variant_start(m_serial_local_t local, m_serial_read_t serial, const char *const field_name[], const int max, int*id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -542,7 +542,7 @@ m_ser1al_json_read_variant_start(m_serial_local_t local, m_serial_read_t serial,
|
||||
/* End reading a variant from the stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_variant_end(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -570,14 +570,14 @@ static const m_serial_read_interface_t m_ser1al_json_read_interface = {
|
||||
};
|
||||
|
||||
/* Initialize the JSON serial object for reading any object from JSON format in the given FILE */
|
||||
static inline void m_serial_json_read_init(m_serial_read_t serial, FILE *f)
|
||||
M_INLINE void m_serial_json_read_init(m_serial_read_t serial, FILE *f)
|
||||
{
|
||||
serial->m_interface = &m_ser1al_json_read_interface;
|
||||
serial->data[0].p = M_ASSIGN_CAST(void*, f);
|
||||
}
|
||||
|
||||
/* Clear the JSON serial object for reading from the FILE */
|
||||
static inline void m_serial_json_read_clear(m_serial_read_t serial)
|
||||
M_INLINE void m_serial_json_read_clear(m_serial_read_t serial)
|
||||
{
|
||||
(void) serial; // Nothing to do
|
||||
}
|
||||
@@ -597,7 +597,7 @@ typedef m_serial_read_t m_serial_json_read_t;
|
||||
|
||||
/* Write the boolean 'data' into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_boolean(m_serial_write_t serial, const bool data)
|
||||
{
|
||||
struct m_string_s *f = (struct m_string_s *)serial->data[0].p;
|
||||
@@ -607,7 +607,7 @@ m_ser1al_str_json_write_boolean(m_serial_write_t serial, const bool data)
|
||||
|
||||
/* Write the integer 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_integer(m_serial_write_t serial,const long long data, const size_t size_of_type)
|
||||
{
|
||||
(void) size_of_type; // Ignored
|
||||
@@ -618,7 +618,7 @@ m_ser1al_str_json_write_integer(m_serial_write_t serial,const long long data, co
|
||||
|
||||
/* Write the float 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_float(m_serial_write_t serial, const long double data, const size_t size_of_type)
|
||||
{
|
||||
(void) size_of_type; // Ignored
|
||||
@@ -629,7 +629,7 @@ m_ser1al_str_json_write_float(m_serial_write_t serial, const long double data, c
|
||||
|
||||
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_string(m_serial_write_t serial, const char data[], size_t length)
|
||||
{
|
||||
M_ASSERT_SLOW(length == strlen(data) );
|
||||
@@ -651,7 +651,7 @@ m_ser1al_str_json_write_string(m_serial_write_t serial, const char data[], size_
|
||||
Initialize 'local' so that it can be used to serialize the array
|
||||
(local is an unique serialization object of the array).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_array_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -663,7 +663,7 @@ m_ser1al_str_json_write_array_start(m_serial_local_t local, m_serial_write_t ser
|
||||
|
||||
/* Write an array separator between elements of an array into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_array_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -674,7 +674,7 @@ m_ser1al_str_json_write_array_next(m_serial_local_t local, m_serial_write_t seri
|
||||
|
||||
/* End the writing of an array into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_array_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -689,7 +689,7 @@ m_ser1al_str_json_write_array_end(m_serial_local_t local, m_serial_write_t seria
|
||||
Initialize 'local' so that it can be used to serialize the map
|
||||
(local is an unique serialization object of the map).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_map_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -701,7 +701,7 @@ m_ser1al_str_json_write_map_start(m_serial_local_t local, m_serial_write_t seria
|
||||
|
||||
/* Write a value separator between element of the same pair of a map into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -712,7 +712,7 @@ m_ser1al_str_json_write_map_value(m_serial_local_t local, m_serial_write_t seria
|
||||
|
||||
/* Write a map separator between elements of a map into the serial stream 'serial' if needed.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_map_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -723,7 +723,7 @@ m_ser1al_str_json_write_map_next(m_serial_local_t local, m_serial_write_t serial
|
||||
|
||||
/* End the writing of a map into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_map_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -736,7 +736,7 @@ m_ser1al_str_json_write_map_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
Initialize 'local' so that it can serial the tuple
|
||||
(local is an unique serialization object of the tuple).
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -747,7 +747,7 @@ m_ser1al_str_json_write_tuple_start(m_serial_local_t local, m_serial_write_t ser
|
||||
|
||||
/* Start writing the field named field_name[index] of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -759,7 +759,7 @@ m_ser1al_str_json_write_tuple_id(m_serial_local_t local, m_serial_write_t serial
|
||||
|
||||
/* End the write of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -773,7 +773,7 @@ m_ser1al_str_json_write_tuple_end(m_serial_local_t local, m_serial_write_t seria
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise
|
||||
Otherwise, the field 'field_name[index]' will be filled.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_variant_start(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -792,7 +792,7 @@ m_ser1al_str_json_write_variant_start(m_serial_local_t local, m_serial_write_t s
|
||||
|
||||
/* End Writing a variant into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_write_variant_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -822,14 +822,14 @@ static const m_serial_write_interface_t m_ser1al_str_json_write_interface = {
|
||||
};
|
||||
|
||||
/* Initialize the JSON serial object for writing any object to JSON format in the given FILE */
|
||||
static inline void m_serial_str_json_write_init(m_serial_write_t serial, m_string_t s)
|
||||
M_INLINE void m_serial_str_json_write_init(m_serial_write_t serial, m_string_t s)
|
||||
{
|
||||
serial->m_interface = &m_ser1al_str_json_write_interface;
|
||||
serial->data[0].p = M_ASSIGN_CAST(struct m_string_s *, s);
|
||||
}
|
||||
|
||||
/* CLear the JSON serial object for writing*/
|
||||
static inline void m_serial_str_json_write_clear(m_serial_write_t serial)
|
||||
M_INLINE void m_serial_str_json_write_clear(m_serial_write_t serial)
|
||||
{
|
||||
(void) serial; // Nothing to do
|
||||
}
|
||||
@@ -847,7 +847,7 @@ typedef m_serial_write_t m_serial_str_json_write_t;
|
||||
/********************************************************************************/
|
||||
|
||||
/* Helper function to read a character and advance the stream */
|
||||
static inline char
|
||||
M_INLINE char
|
||||
m_ser1al_str_json_getc(const char **p)
|
||||
{
|
||||
char c = **p;
|
||||
@@ -857,7 +857,7 @@ m_ser1al_str_json_getc(const char **p)
|
||||
}
|
||||
|
||||
/* Helper function to skip space(s) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_ser1al_str_json_skip (const char **p)
|
||||
{
|
||||
while (isspace (**p)) {
|
||||
@@ -866,7 +866,7 @@ m_ser1al_str_json_skip (const char **p)
|
||||
}
|
||||
|
||||
/* Helper function to read a string with characters not present in reject */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_ser1al_str_json_gets(size_t alloc, char field[], const char reject[], const char **s)
|
||||
{
|
||||
M_ASSERT (alloc > 0);
|
||||
@@ -881,7 +881,7 @@ m_ser1al_str_json_gets(size_t alloc, char field[], const char reject[], const ch
|
||||
/* Read from the stream 'serial' a boolean.
|
||||
Set '*b' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_boolean(m_serial_read_t serial, bool *b){
|
||||
const char **f = &serial->data[0].cstr;
|
||||
m_ser1al_str_json_skip(f);
|
||||
@@ -914,7 +914,7 @@ m_ser1al_str_json_read_boolean(m_serial_read_t serial, bool *b){
|
||||
/* Read from the stream 'serial' an integer that can be represented with 'size_of_type' bytes.
|
||||
Set '*i' with the integer value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_integer(m_serial_read_t serial, long long *i, const size_t size_of_type){
|
||||
(void) size_of_type; // Ignored
|
||||
const char **f = &serial->data[0].cstr;
|
||||
@@ -928,7 +928,7 @@ m_ser1al_str_json_read_integer(m_serial_read_t serial, long long *i, const size_
|
||||
/* Read from the stream 'serial' a float that can be represented with 'size_of_type' bytes.
|
||||
Set '*r' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_float(m_serial_read_t serial, long double *r, const size_t size_of_type){
|
||||
(void) size_of_type; // Ignored
|
||||
const char **f = &serial->data[0].cstr;
|
||||
@@ -942,7 +942,7 @@ m_ser1al_str_json_read_float(m_serial_read_t serial, long double *r, const size_
|
||||
/* Read from the stream 'serial' a string.
|
||||
Set 's' with the string if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_string(m_serial_read_t serial, struct m_string_s *s){
|
||||
const char **f = &serial->data[0].cstr;
|
||||
m_ser1al_str_json_skip(f);
|
||||
@@ -959,7 +959,7 @@ m_ser1al_str_json_read_string(m_serial_read_t serial, struct m_string_s *s){
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends (the array is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_array_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -984,7 +984,7 @@ m_ser1al_str_json_read_array_start(m_serial_local_t local, m_serial_read_t seria
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the array continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the array ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_array_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1001,7 +1001,7 @@ m_ser1al_str_json_read_array_next(m_serial_local_t local, m_serial_read_t serial
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the map ends (the map is empty),
|
||||
m_core_serial_fail() otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_map_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1025,7 +1025,7 @@ m_ser1al_str_json_read_map_start(m_serial_local_t local, m_serial_read_t serial,
|
||||
/* Continue reading from the stream 'serial' the value separator
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1039,7 +1039,7 @@ m_ser1al_str_json_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the map continue,
|
||||
M_SERIAL_OK_DONE if it succeeds and the map ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_map_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1052,7 +1052,7 @@ m_ser1al_str_json_read_map_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
/* Start reading a tuple from the stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1068,7 +1068,7 @@ m_ser1al_str_json_read_tuple_start(m_serial_local_t local, m_serial_read_t seria
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the tuple continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the tuple ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, const char *const field_name [], const int max, int *id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1109,7 +1109,7 @@ m_ser1al_str_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial,
|
||||
Return M_SERIAL_OK_CONTINUE if it succeeds and the variant continues,
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends(variant is empty),
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_variant_start(m_serial_local_t local, m_serial_read_t serial, const char *const field_name[], const int max, int*id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1146,7 +1146,7 @@ m_ser1al_str_json_read_variant_start(m_serial_local_t local, m_serial_read_t ser
|
||||
/* End reading a variant from the stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds and the variant ends,
|
||||
M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_str_json_read_variant_end(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
@@ -1173,14 +1173,14 @@ static const m_serial_read_interface_t m_ser1al_str_json_read_interface = {
|
||||
};
|
||||
|
||||
/* Initialize the JSON serial object for reading any object from JSON format in the given const string */
|
||||
static inline void m_serial_str_json_read_init(m_serial_read_t serial, const char str[])
|
||||
M_INLINE void m_serial_str_json_read_init(m_serial_read_t serial, const char str[])
|
||||
{
|
||||
serial->m_interface = &m_ser1al_str_json_read_interface;
|
||||
serial->data[0].cstr = str;
|
||||
}
|
||||
|
||||
/* Clear the JSON serial object for reading from the FILE */
|
||||
static inline const char *m_serial_str_json_read_clear(m_serial_read_t serial)
|
||||
M_INLINE const char *m_serial_str_json_read_clear(m_serial_read_t serial)
|
||||
{
|
||||
// Nothing to clear. Return pointer to the last data parsed.
|
||||
return serial->data[0].cstr;
|
||||
|
||||
+26
-29
@@ -119,9 +119,6 @@ M_BEGIN_PROTECTED_CODE
|
||||
SWAP(M_F(name, _swap)) \
|
||||
,NAME(name) \
|
||||
,TYPE(M_F(name, _ct)) \
|
||||
,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \
|
||||
,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \
|
||||
,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \
|
||||
)
|
||||
|
||||
// OPLIST to handle a counter of atomic type
|
||||
@@ -139,10 +136,10 @@ M_BEGIN_PROTECTED_CODE
|
||||
IT_CREF(m_shar3d_integer_cref))
|
||||
|
||||
/* Atomic like interface for basic integers */
|
||||
static inline void m_shar3d_integer_init_set(int *p, int val) { *p = val; }
|
||||
static inline int m_shar3d_integer_add(int *p, int val) { int r = *p; *p += val; return r; }
|
||||
static inline int m_shar3d_integer_sub(int *p, int val) { int r = *p; *p -= val; return r; }
|
||||
static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_INLINE void m_shar3d_integer_init_set(int *p, int val) { *p = val; }
|
||||
M_INLINE int m_shar3d_integer_add(int *p, int val) { int r = *p; *p += val; return r; }
|
||||
M_INLINE int m_shar3d_integer_sub(int *p, int val) { int r = *p; *p -= val; return r; }
|
||||
M_INLINE int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
|
||||
|
||||
/********************************** INTERNAL *********************************/
|
||||
@@ -192,13 +189,13 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
/* Define the core functions */
|
||||
#define M_SHAR3D_PTR_DEF_CORE(name, type, oplist, cpt_oplist, shared_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(shared_t shared) \
|
||||
{ \
|
||||
*shared = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init2)(shared_t shared, type *data) \
|
||||
{ \
|
||||
M_ASSERT (shared != NULL); \
|
||||
@@ -221,7 +218,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_new)(shared_t shared) \
|
||||
{ \
|
||||
/* NOTE: Alloc 1 struct with both structures. */ \
|
||||
@@ -242,14 +239,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
} \
|
||||
, /* No INIT */ ) \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _NULL_p)(const shared_t shared) \
|
||||
{ \
|
||||
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
|
||||
return *shared == NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(shared_t dest, \
|
||||
const shared_t shared) \
|
||||
{ \
|
||||
@@ -263,7 +260,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(shared_t dest) \
|
||||
{ \
|
||||
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
|
||||
@@ -284,14 +281,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(shared_t dest) \
|
||||
{ \
|
||||
/* NOTE: Clear will also set dest to NULL */ \
|
||||
M_F(name, _clear)(dest); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(shared_t dest, \
|
||||
const shared_t shared) \
|
||||
{ \
|
||||
@@ -301,7 +298,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_F(name, _init_set)(dest, shared); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(shared_t dest, \
|
||||
shared_t shared) \
|
||||
{ \
|
||||
@@ -312,7 +309,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_SHAR3D_CONTRACT(dest, cpt_oplist); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(shared_t dest, \
|
||||
shared_t shared) \
|
||||
{ \
|
||||
@@ -323,7 +320,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_F(name, _init_move)(dest, shared); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(shared_t p1, \
|
||||
shared_t p2) \
|
||||
{ \
|
||||
@@ -335,7 +332,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_SHAR3D_CONTRACT(p2, cpt_oplist); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(const shared_t p1, \
|
||||
const shared_t p2) \
|
||||
{ \
|
||||
@@ -344,7 +341,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
return *p1 == *p2; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(const shared_t shared) \
|
||||
{ \
|
||||
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
|
||||
@@ -354,7 +351,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
return M_CONST_CAST (type, data); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(shared_t shared) \
|
||||
{ \
|
||||
M_SHAR3D_CONTRACT(shared, cpt_oplist); \
|
||||
@@ -413,7 +410,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
|
||||
/* Define the core functions */
|
||||
#define M_SHAR3D_RESOURCE_DEF_CORE(name, type, oplist, shared_t, it_t) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(shared_t s, size_t n) \
|
||||
{ \
|
||||
M_ASSERT(s != NULL); \
|
||||
@@ -431,7 +428,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
M_SHAR3D_RESOURCE_CONTRACT(s); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(shared_t s) \
|
||||
{ \
|
||||
M_SHAR3D_RESOURCE_CONTRACT(s); \
|
||||
@@ -444,7 +441,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
m_genint_clear(s->core); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it)(it_t it, shared_t s) \
|
||||
{ \
|
||||
M_SHAR3D_RESOURCE_CONTRACT(s); \
|
||||
@@ -458,14 +455,14 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL); \
|
||||
return it->idx == M_GENINT_ERROR; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
|
||||
@@ -473,7 +470,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
return &it->ref->buffer[it->idx].x; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(it_t it) \
|
||||
{ \
|
||||
M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
|
||||
@@ -481,7 +478,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
return M_CONST_CAST (type, &it->ref->buffer[it->idx].x); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _end)(it_t it, shared_t s) \
|
||||
{ \
|
||||
M_SHAR3D_RESOURCE_CONTRACT(s); \
|
||||
@@ -497,7 +494,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t itd, it_t its) \
|
||||
{ \
|
||||
M_ASSERT (itd != NULL && its != NULL); \
|
||||
|
||||
+33
-33
@@ -197,7 +197,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
/* Define the core functions */
|
||||
#define M_SNAPSH0T_SPSC_DEF_CORE(name, type, oplist, snapshot_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(snapshot_t snap) \
|
||||
{ \
|
||||
M_ASSERT(snap != NULL); \
|
||||
@@ -208,7 +208,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -218,7 +218,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* const is missing for org due to use of atomic_load of org */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(snapshot_t snap, snapshot_t org) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(org); \
|
||||
@@ -231,7 +231,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* const is missing for org due to use of atomic_load of org */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(snapshot_t snap, snapshot_t org) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -244,7 +244,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(INIT_MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(snapshot_t snap, snapshot_t org) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(org); \
|
||||
@@ -259,7 +259,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
,) /* IF_METHOD (INIT_MOVE) */ \
|
||||
\
|
||||
M_IF_METHOD(MOVE, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(snapshot_t snap, \
|
||||
snapshot_t org) \
|
||||
{ \
|
||||
@@ -275,7 +275,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
,) /* IF_METHOD (MOVE) */ \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _write)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -294,7 +294,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
return &snap->data[M_SNAPSH0T_SPSC_W(nextFlags)].x; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _read)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -319,7 +319,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* Non const due to use of atomic_load */ \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _updated_p)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -328,7 +328,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* Non const due to use of atomic_load */ \
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _get_write_buffer)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -337,7 +337,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
} \
|
||||
\
|
||||
/* Non const due to use of atomic_load */ \
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _get_read_buffer)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPSC_CONTRACT(snap); \
|
||||
@@ -382,7 +382,7 @@ typedef struct m_snapsh0t_mrsw_s {
|
||||
} while (0)
|
||||
|
||||
/* Initialize m_snapsh0t_mrsw_ct for n readers (constructor) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_snapsh0t_mrsw_init(m_snapsh0t_mrsw_ct s, size_t n)
|
||||
{
|
||||
M_ASSERT (s != NULL);
|
||||
@@ -415,7 +415,7 @@ m_snapsh0t_mrsw_init(m_snapsh0t_mrsw_ct s, size_t n)
|
||||
}
|
||||
|
||||
/* Clear m_snapsh0t_mrsw_ct (destructor) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_snapsh0t_mrsw_clear(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -426,7 +426,7 @@ m_snapsh0t_mrsw_clear(m_snapsh0t_mrsw_ct s)
|
||||
}
|
||||
|
||||
/* Return the current index that is written in the buffer */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_get_write_idx(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -434,7 +434,7 @@ m_snapsh0t_mrsw_get_write_idx(m_snapsh0t_mrsw_ct s)
|
||||
}
|
||||
|
||||
/* Return the number of readers */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_size(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -443,7 +443,7 @@ m_snapsh0t_mrsw_size(m_snapsh0t_mrsw_ct s)
|
||||
|
||||
/* Give the current index that is written to the readers,
|
||||
and return new available index for the writer thread */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_write_idx(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -485,7 +485,7 @@ m_snapsh0t_mrsw_write_idx(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
}
|
||||
|
||||
/* Perform a swap of the current write buffer and return a new one */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_write(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
s->currentWrite = m_snapsh0t_mrsw_write_idx(s, s->currentWrite);
|
||||
@@ -494,7 +494,7 @@ m_snapsh0t_mrsw_write(m_snapsh0t_mrsw_ct s)
|
||||
}
|
||||
|
||||
/* Start writing to the write buffer and return its index */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_write_start(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -509,7 +509,7 @@ m_snapsh0t_mrsw_write_start(m_snapsh0t_mrsw_ct s)
|
||||
}
|
||||
|
||||
/* End writing to the given write buffer */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_snapsh0t_mrsw_write_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -531,7 +531,7 @@ m_snapsh0t_mrsw_write_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
}
|
||||
|
||||
/* Start reading the latest written buffer and return the index to it */
|
||||
static inline unsigned int
|
||||
M_INLINE unsigned int
|
||||
m_snapsh0t_mrsw_read_start(m_snapsh0t_mrsw_ct s)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -574,7 +574,7 @@ m_snapsh0t_mrsw_read_start(m_snapsh0t_mrsw_ct s)
|
||||
}
|
||||
|
||||
/* End the reading the given buffer */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
{
|
||||
M_SNAPSH0T_SPMC_INT_CONTRACT(s);
|
||||
@@ -639,7 +639,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
/* Define the core functions */
|
||||
#define M_SNAPSH0T_SPMC_DEF_CORE(name, type, oplist, snapshot_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(snapshot_t snap, size_t nReader) \
|
||||
{ \
|
||||
M_ASSERT (snap != NULL); \
|
||||
@@ -658,7 +658,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
@@ -670,7 +670,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
m_snapsh0t_mrsw_clear(snap->core); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _write)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
@@ -678,7 +678,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
return &snap->data[idx].x; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _read_start)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
@@ -686,7 +686,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
return M_CONST_CAST(type, &snap->data[idx].x); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_end)(snapshot_t snap, type const *old) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
@@ -700,7 +700,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
m_snapsh0t_mrsw_read_end(snap->core, idx); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _get_write_buffer)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap); \
|
||||
@@ -746,7 +746,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
/* Define the core functions */
|
||||
#define M_SNAPSH0T_MPMC_DEF_CORE(name, type, oplist, snapshot_t) \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(snapshot_t snap, size_t nReader, size_t nWriter) \
|
||||
{ \
|
||||
M_F(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \
|
||||
@@ -755,13 +755,13 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
m_snapsh0t_mrsw_write_end(snap->core->core, idx); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(snapshot_t snap) \
|
||||
{ \
|
||||
M_F(name, _mrsw_clear)(snap->core); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _write_start)(snapshot_t snap) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap->core); \
|
||||
@@ -769,7 +769,7 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
return &snap->core->data[idx].x; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _write_end)(snapshot_t snap, type *old) \
|
||||
{ \
|
||||
M_SNAPSH0T_SPMC_CONTRACT(snap->core); \
|
||||
@@ -782,13 +782,13 @@ m_snapsh0t_mrsw_read_end(m_snapsh0t_mrsw_ct s, unsigned int idx)
|
||||
m_snapsh0t_mrsw_write_end(snap->core->core, idx); \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _read_start)(snapshot_t snap) \
|
||||
{ \
|
||||
return M_F(name, _mrsw_read_start)(snap->core); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _read_end)(snapshot_t snap, type const *old) \
|
||||
{ \
|
||||
M_F(name, _mrsw_read_end)(snap->core, old); \
|
||||
|
||||
+239
-143
File diff suppressed because it is too large.
Load diff
+266
-47
@@ -27,7 +27,9 @@
|
||||
|
||||
/* Auto-detect the thread backend to use if the user has not override it */
|
||||
#ifndef M_USE_THREAD_BACKEND
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \
|
||||
# if defined(INC_FREERTOS_H)
|
||||
# define M_USE_THREAD_BACKEND 4
|
||||
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \
|
||||
&& !defined(__STDC_NO_THREADS__)
|
||||
# define M_USE_THREAD_BACKEND 1
|
||||
# elif defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||
@@ -58,7 +60,7 @@ typedef cnd_t m_cond_t[1];
|
||||
typedef thrd_t m_thread_t[1];
|
||||
|
||||
/* Initialize the mutex (constructor) */
|
||||
static inline void m_mutex_init(m_mutex_t m)
|
||||
M_INLINE void m_mutex_init(m_mutex_t m)
|
||||
{
|
||||
int rc = mtx_init(m, mtx_plain);
|
||||
// Abort program in case of initialization failure
|
||||
@@ -67,25 +69,25 @@ static inline void m_mutex_init(m_mutex_t m)
|
||||
}
|
||||
|
||||
/* Clear the mutex (destructor) */
|
||||
static inline void m_mutex_clear(m_mutex_t m)
|
||||
M_INLINE void m_mutex_clear(m_mutex_t m)
|
||||
{
|
||||
mtx_destroy(m);
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
static inline void m_mutex_lock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_lock(m_mutex_t m)
|
||||
{
|
||||
mtx_lock(m);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
static inline void m_mutex_unlock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_unlock(m_mutex_t m)
|
||||
{
|
||||
mtx_unlock(m);
|
||||
}
|
||||
|
||||
/* Initialize the condition variable (constructor) */
|
||||
static inline void m_cond_init(m_cond_t c)
|
||||
M_INLINE void m_cond_init(m_cond_t c)
|
||||
{
|
||||
int rc = cnd_init(c);
|
||||
// Abort program in case of initialization failure
|
||||
@@ -94,31 +96,31 @@ static inline void m_cond_init(m_cond_t c)
|
||||
}
|
||||
|
||||
/* Clear the condition variable (destructor) */
|
||||
static inline void m_cond_clear(m_cond_t c)
|
||||
M_INLINE void m_cond_clear(m_cond_t c)
|
||||
{
|
||||
cnd_destroy(c);
|
||||
}
|
||||
|
||||
/* Signal the condition variable to at least one waiting thread */
|
||||
static inline void m_cond_signal(m_cond_t c)
|
||||
M_INLINE void m_cond_signal(m_cond_t c)
|
||||
{
|
||||
cnd_signal(c);
|
||||
}
|
||||
|
||||
/* Signal the condition variable to all waiting threads */
|
||||
static inline void m_cond_broadcast(m_cond_t c)
|
||||
M_INLINE void m_cond_broadcast(m_cond_t c)
|
||||
{
|
||||
cnd_broadcast(c);
|
||||
}
|
||||
|
||||
/* Wait for signaling the condition variable by another thread */
|
||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
M_INLINE void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
{
|
||||
cnd_wait(c, m);
|
||||
}
|
||||
|
||||
/* Create the thread (constructor) and start it */
|
||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
||||
M_INLINE void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
||||
{
|
||||
int rc = thrd_create(t, (int(*)(void*))(void(*)(void))func, arg);
|
||||
// Abort program in case of initialization failure
|
||||
@@ -126,7 +128,7 @@ static inline void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
||||
}
|
||||
|
||||
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||
static inline void m_thread_join(m_thread_t t)
|
||||
M_INLINE void m_thread_join(m_thread_t t)
|
||||
{
|
||||
int rc = thrd_join(*t, NULL);
|
||||
M_ASSERT (rc == thrd_success);
|
||||
@@ -136,14 +138,14 @@ static inline void m_thread_join(m_thread_t t)
|
||||
|
||||
/* The thread has nothing meaningfull to do.
|
||||
Inform the OS to let other threads be scheduled */
|
||||
static inline void m_thread_yield(void)
|
||||
M_INLINE void m_thread_yield(void)
|
||||
{
|
||||
thrd_yield();
|
||||
}
|
||||
|
||||
/* Sleep the thread for at least usec microseconds.
|
||||
Return true if the sleep was successful */
|
||||
static inline bool m_thread_sleep(unsigned long long usec)
|
||||
Return true if the sleep was successful (or we cannot know) */
|
||||
M_INLINE bool m_thread_sleep(unsigned long long usec)
|
||||
{
|
||||
struct timespec tv;
|
||||
tv.tv_sec = (long) (usec / 1000000ULL);
|
||||
@@ -159,7 +161,7 @@ typedef once_flag m_once_t[1];
|
||||
#define M_ONCE_INIT_VALUE { ONCE_FLAG_INIT }
|
||||
|
||||
// Call the function exactly once
|
||||
static inline void m_once_call(m_once_t o, void (*func)(void))
|
||||
M_INLINE void m_once_call(m_once_t o, void (*func)(void))
|
||||
{
|
||||
call_once(o,func);
|
||||
}
|
||||
@@ -223,68 +225,68 @@ typedef CRITICAL_SECTION m_mutex_t[1];
|
||||
typedef CONDITION_VARIABLE m_cond_t[1];
|
||||
|
||||
/* Initialize a mutex (Constructor)*/
|
||||
static inline void m_mutex_init(m_mutex_t m)
|
||||
M_INLINE void m_mutex_init(m_mutex_t m)
|
||||
{
|
||||
InitializeCriticalSection(m);
|
||||
}
|
||||
|
||||
/* Clear a mutex (destructor) */
|
||||
static inline void m_mutex_clear(m_mutex_t m)
|
||||
M_INLINE void m_mutex_clear(m_mutex_t m)
|
||||
{
|
||||
DeleteCriticalSection(m);
|
||||
}
|
||||
|
||||
/* Lock a mutex */
|
||||
static inline void m_mutex_lock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_lock(m_mutex_t m)
|
||||
{
|
||||
EnterCriticalSection(m);
|
||||
}
|
||||
|
||||
/* Unlock a mutex */
|
||||
static inline void m_mutex_unlock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_unlock(m_mutex_t m)
|
||||
{
|
||||
LeaveCriticalSection(m);
|
||||
}
|
||||
|
||||
/* Initialize a condition variable (constructor) */
|
||||
static inline void m_cond_init(m_cond_t c)
|
||||
M_INLINE void m_cond_init(m_cond_t c)
|
||||
{
|
||||
InitializeConditionVariable(c);
|
||||
}
|
||||
|
||||
/* Clear a condition variable (destructor) */
|
||||
static inline void m_cond_clear(m_cond_t c)
|
||||
M_INLINE void m_cond_clear(m_cond_t c)
|
||||
{
|
||||
(void) c; // There is no destructor for this object.
|
||||
}
|
||||
|
||||
/* Signal a condition variable to at least one waiting thread */
|
||||
static inline void m_cond_signal(m_cond_t c)
|
||||
M_INLINE void m_cond_signal(m_cond_t c)
|
||||
{
|
||||
WakeConditionVariable(c);
|
||||
}
|
||||
|
||||
/* Signal a condition variable to all waiting threads */
|
||||
static inline void m_cond_broadcast(m_cond_t c)
|
||||
M_INLINE void m_cond_broadcast(m_cond_t c)
|
||||
{
|
||||
WakeAllConditionVariable(c);
|
||||
}
|
||||
|
||||
/* Wait for a condition variable */
|
||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
M_INLINE void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
{
|
||||
SleepConditionVariableCS(c, m, INFINITE);
|
||||
}
|
||||
|
||||
/* Create a thread (constructor) and start it */
|
||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||
M_INLINE void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||
{
|
||||
*t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (uintptr_t) func, arg, 0, NULL);
|
||||
M_ASSERT_INIT (*t != NULL, "thread");
|
||||
}
|
||||
|
||||
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||
static inline void m_thread_join(m_thread_t t)
|
||||
M_INLINE void m_thread_join(m_thread_t t)
|
||||
{
|
||||
DWORD dwWaitResult = WaitForSingleObject(*t, INFINITE);
|
||||
(void) dwWaitResult;
|
||||
@@ -294,14 +296,14 @@ static inline void m_thread_join(m_thread_t t)
|
||||
|
||||
/* The thread has nothing meaningfull to do.
|
||||
Inform the OS to let other threads be scheduled */
|
||||
static inline void m_thread_yield(void)
|
||||
M_INLINE void m_thread_yield(void)
|
||||
{
|
||||
Sleep(0);
|
||||
}
|
||||
|
||||
/* Sleep the thread for at least usec microseconds
|
||||
Return true if the sleep was successful */
|
||||
static inline bool m_thread_sleep(unsigned long long usec)
|
||||
M_INLINE bool m_thread_sleep(unsigned long long usec)
|
||||
{
|
||||
LARGE_INTEGER ft;
|
||||
M_ASSERT (usec <= LLONG_MAX);
|
||||
@@ -317,7 +319,7 @@ static inline bool m_thread_sleep(unsigned long long usec)
|
||||
|
||||
typedef INIT_ONCE m_once_t[1];
|
||||
#define M_ONCE_INIT_VALUE { INIT_ONCE_STATIC_INIT }
|
||||
static inline BOOL CALLBACK m_once_callback( PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
|
||||
M_INLINE BOOL CALLBACK m_once_callback( PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
|
||||
{
|
||||
void (*func)(void);
|
||||
(void) InitOnce;
|
||||
@@ -326,7 +328,7 @@ static inline BOOL CALLBACK m_once_callback( PINIT_ONCE InitOnce, PVOID Paramete
|
||||
(*func)();
|
||||
return TRUE;
|
||||
}
|
||||
static inline void m_once_call(m_once_t o, void (*func)(void))
|
||||
M_INLINE void m_once_call(m_once_t o, void (*func)(void))
|
||||
{
|
||||
InitOnceExecuteOnce(o, m_once_callback, (void*)(intptr_t)func, NULL);
|
||||
}
|
||||
@@ -343,7 +345,7 @@ M_END_PROTECTED_CODE
|
||||
|
||||
|
||||
/**************************** PTHREAD version ******************************/
|
||||
#else
|
||||
#elif M_USE_THREAD_BACKEND == 3
|
||||
|
||||
#include <pthread.h>
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
@@ -368,7 +370,7 @@ typedef pthread_cond_t m_cond_t[1];
|
||||
typedef pthread_t m_thread_t[1];
|
||||
|
||||
/* Initialize the mutex (constructor) */
|
||||
static inline void m_mutex_init(m_mutex_t m)
|
||||
M_INLINE void m_mutex_init(m_mutex_t m)
|
||||
{
|
||||
int _rc = pthread_mutex_init(m, NULL);
|
||||
// Abort program in case of initialization failure
|
||||
@@ -377,19 +379,19 @@ static inline void m_mutex_init(m_mutex_t m)
|
||||
}
|
||||
|
||||
/* Clear the mutex (destructor) */
|
||||
static inline void m_mutex_clear(m_mutex_t m)
|
||||
M_INLINE void m_mutex_clear(m_mutex_t m)
|
||||
{
|
||||
pthread_mutex_destroy(m);
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
static inline void m_mutex_lock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_lock(m_mutex_t m)
|
||||
{
|
||||
pthread_mutex_lock(m);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
static inline void m_mutex_unlock(m_mutex_t m)
|
||||
M_INLINE void m_mutex_unlock(m_mutex_t m)
|
||||
{
|
||||
pthread_mutex_unlock(m);
|
||||
}
|
||||
@@ -398,13 +400,13 @@ static inline void m_mutex_unlock(m_mutex_t m)
|
||||
#define M_MUTEXI_INIT_VALUE { PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
/* Internal function compatible with lazy lock */
|
||||
static inline void m_mutexi_lazy_lock(m_mutex_t m)
|
||||
M_INLINE void m_mutexi_lazy_lock(m_mutex_t m)
|
||||
{
|
||||
pthread_mutex_lock(m);
|
||||
}
|
||||
|
||||
/* Initialize the condition variable (constructor) */
|
||||
static inline void m_cond_init(m_cond_t c)
|
||||
M_INLINE void m_cond_init(m_cond_t c)
|
||||
{
|
||||
int _rc = pthread_cond_init(c, NULL);
|
||||
// Abort program in case of initialization failure
|
||||
@@ -413,38 +415,38 @@ static inline void m_cond_init(m_cond_t c)
|
||||
}
|
||||
|
||||
/* Clear the condition variable (destructor) */
|
||||
static inline void m_cond_clear(m_cond_t c)
|
||||
M_INLINE void m_cond_clear(m_cond_t c)
|
||||
{
|
||||
pthread_cond_destroy(c);
|
||||
}
|
||||
|
||||
/* Signal a condition variable to at least a waiting thread */
|
||||
static inline void m_cond_signal(m_cond_t c)
|
||||
M_INLINE void m_cond_signal(m_cond_t c)
|
||||
{
|
||||
pthread_cond_signal(c);
|
||||
}
|
||||
|
||||
/* Signal a condition variable to all waiting threads */
|
||||
static inline void m_cond_broadcast(m_cond_t c)
|
||||
M_INLINE void m_cond_broadcast(m_cond_t c)
|
||||
{
|
||||
pthread_cond_broadcast(c);
|
||||
}
|
||||
|
||||
/* Waiting for a condition variable */
|
||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
M_INLINE void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
{
|
||||
pthread_cond_wait(c, m);
|
||||
}
|
||||
|
||||
/* Create a thread (constructor) and start it */
|
||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||
M_INLINE void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||
{
|
||||
int _rc = pthread_create(t, NULL, (void*(*)(void*))(void(*)(void))func, arg);
|
||||
M_ASSERT_INIT (_rc == 0, "thread");
|
||||
}
|
||||
|
||||
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||
static inline void m_thread_join(m_thread_t t)
|
||||
M_INLINE void m_thread_join(m_thread_t t)
|
||||
{
|
||||
int _rc = pthread_join(*t, NULL);
|
||||
(void)_rc; // Avoid warning about variable unused.
|
||||
@@ -453,7 +455,7 @@ static inline void m_thread_join(m_thread_t t)
|
||||
|
||||
/* The thread has nothing meaningfull to do.
|
||||
Inform the OS to let other threads be scheduled */
|
||||
static inline void m_thread_yield(void)
|
||||
M_INLINE void m_thread_yield(void)
|
||||
{
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
sched_yield();
|
||||
@@ -462,7 +464,7 @@ static inline void m_thread_yield(void)
|
||||
|
||||
/* Sleep for at least usec microseconds
|
||||
Return true if the sleep was successful */
|
||||
static inline bool m_thread_sleep(unsigned long long usec)
|
||||
M_INLINE bool m_thread_sleep(unsigned long long usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
/* We don't want to use usleep or nanosleep so that
|
||||
@@ -475,7 +477,7 @@ static inline bool m_thread_sleep(unsigned long long usec)
|
||||
|
||||
typedef pthread_once_t m_once_t[1];
|
||||
#define M_ONCE_INIT_VALUE { PTHREAD_ONCE_INIT }
|
||||
static inline void m_once_call(m_once_t o, void (*func)(void))
|
||||
M_INLINE void m_once_call(m_once_t o, void (*func)(void))
|
||||
{
|
||||
pthread_once(o,func);
|
||||
}
|
||||
@@ -488,6 +490,223 @@ static inline void m_once_call(m_once_t o, void (*func)(void))
|
||||
|
||||
M_END_PROTECTED_CODE
|
||||
|
||||
/****************************** FreeRTOS version ********************************/
|
||||
#elif M_USE_THREAD_BACKEND == 4
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <semphr.h>
|
||||
#include <task.h>
|
||||
#include "m-core.h"
|
||||
|
||||
M_BEGIN_PROTECTED_CODE
|
||||
|
||||
/* Default value for the stack */
|
||||
#ifndef M_USE_TASK_STACK_SIZE
|
||||
#define M_USE_TASK_STACK_SIZE configMINIMAL_STACK_SIZE
|
||||
#endif
|
||||
|
||||
/* Default value for the priority tasks */
|
||||
#ifndef M_USE_TASK_PRIORITY
|
||||
#define M_USE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
#endif
|
||||
|
||||
/* Define a mutex type based on FreeRTOS definition */
|
||||
typedef struct m_mutex_s {
|
||||
SemaphoreHandle_t handle;
|
||||
StaticSemaphore_t MutexBuffer;
|
||||
} m_mutex_t[1];
|
||||
|
||||
/* Define a thread type based on FreeRTOS definition */
|
||||
typedef struct m_cond_s {
|
||||
SemaphoreHandle_t handle;
|
||||
StaticSemaphore_t SemBuffer;
|
||||
unsigned int NumThreadWaiting;
|
||||
} m_cond_t[1];
|
||||
|
||||
/* Define a thread type based on FreeRTOS definition */
|
||||
typedef struct m_thread_s {
|
||||
SemaphoreHandle_t SemHandle;
|
||||
StaticSemaphore_t SemBuffer;
|
||||
TaskHandle_t TaskHandle;
|
||||
StaticTask_t TaskBuffer;
|
||||
void (*EntryPoint)(void *);
|
||||
void* ArgsEntryPoint;
|
||||
StackType_t* StackBuffer;
|
||||
} m_thread_t[1];
|
||||
|
||||
/* Initialize the mutex (constructor) */
|
||||
M_INLINE void m_mutex_init(m_mutex_t m)
|
||||
{
|
||||
/* Create a mutex semaphore without using any dynamic allocation */
|
||||
m->handle = xSemaphoreCreateMutexStatic(&m->MutexBuffer);
|
||||
// It cannot fail, so we won't use M_ASSERT_INIT
|
||||
M_ASSERT(m->handle);
|
||||
}
|
||||
|
||||
/* Clear the mutex (destructor) */
|
||||
M_INLINE void m_mutex_clear(m_mutex_t m)
|
||||
{
|
||||
vSemaphoreDelete(m->handle);
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
M_INLINE void m_mutex_lock(m_mutex_t m)
|
||||
{
|
||||
xSemaphoreTake(m->handle, portMAX_DELAY);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
M_INLINE void m_mutex_unlock(m_mutex_t m)
|
||||
{
|
||||
xSemaphoreGive(m->handle);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the condition variable (constructor) */
|
||||
M_INLINE void m_cond_init(m_cond_t c)
|
||||
{
|
||||
c->NumThreadWaiting = 0;
|
||||
// Create a semaphore to implement the conditional variable
|
||||
// Initial value is 0 and valid range is <= 0
|
||||
c->handle = xSemaphoreCreateCountingStatic( INT_MAX, 0, &c->SemBuffer );
|
||||
// It cannot fail, so we won't use M_ASSERT_INIT
|
||||
M_ASSERT(c->handle);
|
||||
}
|
||||
|
||||
/* Clear the condition variable (destructor) */
|
||||
M_INLINE void m_cond_clear(m_cond_t c)
|
||||
{
|
||||
vSemaphoreDelete(c->handle);
|
||||
}
|
||||
|
||||
/* Signal the condition variable to at least one waiting thread */
|
||||
M_INLINE void m_cond_signal(m_cond_t c)
|
||||
{
|
||||
// This function is called within the mutex lock
|
||||
// NumThreadWaiting doesn't need to be atomic
|
||||
if (c->NumThreadWaiting > 0) {
|
||||
// Wakeup one thread by posting on the semaphore
|
||||
xSemaphoreGive(c->handle);
|
||||
} // Otherwise there is no waiting thread, so nothing to signal
|
||||
}
|
||||
|
||||
/* Signal the condition variable to all waiting threads */
|
||||
M_INLINE void m_cond_broadcast(m_cond_t c)
|
||||
{
|
||||
// This function is called within the mutex lock
|
||||
// NumThreadWaiting doesn't need to be atomic
|
||||
if (c->NumThreadWaiting > 0) {
|
||||
// Wakeup all thread by posting on the semaphore
|
||||
// as many times as there are waiting threads
|
||||
for(unsigned i = 0; i < c->NumThreadWaiting; i++) {
|
||||
xSemaphoreGive(c->handle);
|
||||
}
|
||||
} // Otherwise there is no waiting thread, so nothing to signal
|
||||
}
|
||||
|
||||
/* Wait for signaling the condition variable by another thread */
|
||||
M_INLINE void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||
{
|
||||
// This function is called within the mutex lock
|
||||
// Increment the number of waiting thread
|
||||
c->NumThreadWaiting ++;
|
||||
m_mutex_unlock(m);
|
||||
// Wait for post in the semaphore
|
||||
xSemaphoreTake(c->handle, portMAX_DELAY);
|
||||
m_mutex_lock(m);
|
||||
c->NumThreadWaiting --;
|
||||
}
|
||||
|
||||
M_INLINE void m_thr3ad_wrapper( void *args)
|
||||
{
|
||||
struct m_thread_s *thread_ptr = args;
|
||||
thread_ptr->EntryPoint(thread_ptr->ArgsEntryPoint);
|
||||
// Give back the semaphore.
|
||||
xSemaphoreGive(thread_ptr->SemHandle);
|
||||
// Wait for destruction
|
||||
while (true) { vTaskSuspend(NULL); }
|
||||
}
|
||||
|
||||
/* Create the thread (constructor) and start it */
|
||||
M_INLINE void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
||||
{
|
||||
// Create a semaphore to implement the final wait
|
||||
t->SemHandle = xSemaphoreCreateCountingStatic( 1, 0, &t->SemBuffer );
|
||||
M_ASSERT(t->SemHandle);
|
||||
// Save the argument to the thread
|
||||
t->EntryPoint = func;
|
||||
t->ArgsEntryPoint = arg;
|
||||
|
||||
// Allocate the stack
|
||||
t->StackBuffer = pvPortMalloc( sizeof (StackType_t) * M_USE_TASK_STACK_SIZE);
|
||||
M_ASSERT_INIT(t->StackBuffer, "STACK");
|
||||
|
||||
// Create the task without using any dynamic allocation
|
||||
t->TaskHandle = xTaskCreateStatic(m_thr3ad_wrapper, "M*LIB", M_USE_TASK_STACK_SIZE, (void*) t, M_USE_TASK_PRIORITY, t->StackBuffer, &t->TaskBuffer);
|
||||
// It cannot fail, so we won't use M_ASSERT_INIT
|
||||
M_ASSERT(t->TaskHandle);
|
||||
}
|
||||
|
||||
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||
M_INLINE void m_thread_join(m_thread_t t)
|
||||
{
|
||||
xSemaphoreTake(t->SemHandle, portMAX_DELAY);
|
||||
vTaskDelete(t->TaskHandle);
|
||||
vPortFree(t->StackBuffer);
|
||||
vSemaphoreDelete(t->SemHandle);
|
||||
t->TaskHandle = 0;
|
||||
t->StackBuffer = 0;
|
||||
t->SemHandle = 0;
|
||||
}
|
||||
|
||||
/* The thread has nothing meaningfull to do.
|
||||
Inform the OS to let other threads be scheduled */
|
||||
M_INLINE void m_thread_yield(void)
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
|
||||
/* Sleep the thread for at least usec microseconds.
|
||||
Return true if the sleep was successful */
|
||||
M_INLINE bool m_thread_sleep(unsigned long long usec)
|
||||
{
|
||||
TickType_t delay = (TickType_t) (usec / portTICK_PERIOD_MS / 1000ULL);
|
||||
vTaskDelay(delay);
|
||||
return true;
|
||||
}
|
||||
|
||||
// a helper structure for m_once_call
|
||||
typedef struct {
|
||||
atomic_int count;
|
||||
} m_once_t[1];
|
||||
|
||||
// Initial value for m_once_t
|
||||
#define M_ONCE_INIT_VALUE { { ATOMIC_VAR_INIT(0) } }
|
||||
|
||||
// Call the function exactly once
|
||||
M_INLINE void m_once_call(m_once_t o, void (*func)(void))
|
||||
{
|
||||
if (atomic_load(&o->count) != 2) {
|
||||
int n = 0;
|
||||
if (atomic_compare_exchange_strong( &o->count, &n, 1)) {
|
||||
// First thread success
|
||||
func();
|
||||
atomic_store(&o->count, 2);
|
||||
}
|
||||
// Wait for function call (FIXME: priority inversion possible?)
|
||||
while (atomic_load(&o->count) != 2) { m_thread_yield(); }
|
||||
} // Already called. Nothing to do
|
||||
}
|
||||
|
||||
// Attribute to use to allocate a global variable to a thread.
|
||||
#define M_THREAD_ATTR __thread
|
||||
|
||||
M_END_PROTECTED_CODE
|
||||
|
||||
/******************************** INVALID VALUE **********************************/
|
||||
|
||||
#else
|
||||
# error Value of M_USE_THREAD_BACKEND is incorrect. Please see the documentation for valid usage.
|
||||
#endif
|
||||
|
||||
// TODO: Obsolete M_LOCK macro.
|
||||
|
||||
@@ -204,7 +204,7 @@ typedef int32_t m_tr33_index_t;
|
||||
/* Define the core & unique methods of a tree */
|
||||
#define M_TR33_DEF_P4_CORE(name, type, oplist, tree_t, it_t) \
|
||||
/* Initialize a generic tree (empty) */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init)(tree_t tree) { \
|
||||
tree->size = 0; \
|
||||
tree->capacity = 0; \
|
||||
@@ -215,7 +215,7 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reset)(tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
if (tree->size > 0) { \
|
||||
@@ -241,7 +241,7 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _clear)(tree_t tree) { \
|
||||
M_F(name, _reset)(tree); \
|
||||
struct M_F(name,_node_s)*ptr = tree->tab == NULL ? NULL : tree->tab-1;\
|
||||
@@ -251,7 +251,7 @@ typedef int32_t m_tr33_index_t;
|
||||
tree->tab = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _reserve)(tree_t tree, size_t alloc) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
/* Nothing to do if the request is lower than the current capacity. */ \
|
||||
@@ -298,14 +298,14 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _lock)(tree_t tree, bool lock) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
tree->allow_realloc = lock ? INT32_MAX : 0; \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline m_tr33_index_t \
|
||||
M_INLINE m_tr33_index_t \
|
||||
M_C3(m_tr33_, name, _alloc_node)(tree_t tree) { \
|
||||
m_tr33_index_t ret = tree->free_index; \
|
||||
if (M_UNLIKELY(ret < 0)) { \
|
||||
@@ -350,7 +350,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_tr33_, name, _free_node)(tree_t tree, m_tr33_index_t i) { \
|
||||
tree->tab[i].parent = M_TR33_NO_NODE; \
|
||||
tree->tab[i].left = M_TR33_NO_NODE; \
|
||||
@@ -360,7 +360,7 @@ typedef int32_t m_tr33_index_t;
|
||||
tree->free_index = i; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _set_root)(tree_t tree, type const data) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
M_F(name, _reset)(tree); \
|
||||
@@ -380,7 +380,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* The iterator references the first root node */ \
|
||||
/* usually for pre-order walk */ \
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _it)(tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
it_t it; \
|
||||
@@ -390,7 +390,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _it_end)(tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
it_t it; \
|
||||
@@ -400,53 +400,53 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _end_p)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, false); \
|
||||
return it.index < 0; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _ref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
return &it.tree->tab[it.index].data; \
|
||||
} \
|
||||
\
|
||||
static inline type const * \
|
||||
M_INLINE type const * \
|
||||
M_F(name, _cref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
return M_CONST_CAST(type, &it.tree->tab[it.index].data); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _up_ref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = it.tree->tab[it.index].parent; \
|
||||
return i < 0 ? NULL : &it.tree->tab[i].data; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _down_ref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = it.tree->tab[it.index].child; \
|
||||
return i < 0 ? NULL : &it.tree->tab[i].data; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _left_ref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = it.tree->tab[it.index].left; \
|
||||
return i < 0 ? NULL : &it.tree->tab[i].data; \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _right_ref)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = it.tree->tab[it.index].right; \
|
||||
return i < 0 ? NULL : &it.tree->tab[i].data; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_up_raw)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = M_C3(m_tr33_, name, _alloc_node)(it.tree); \
|
||||
@@ -476,7 +476,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_up)(it_t pos, type const data) { \
|
||||
it_t it = M_F(name, _insert_up_raw)(pos); \
|
||||
M_CALL_INIT_SET(oplist, it.tree->tab[it.index].data, data); \
|
||||
@@ -484,7 +484,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _move_up)(it_t pos, type *data) { \
|
||||
it_t it = M_F(name, _insert_up_raw)(pos); \
|
||||
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
|
||||
@@ -492,7 +492,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_down_raw)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t i = M_C3(m_tr33_, name, _alloc_node)(it.tree); \
|
||||
@@ -513,7 +513,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_down)(it_t pos, type const data) { \
|
||||
it_t it = M_F(name, _insert_down_raw)(pos); \
|
||||
M_CALL_INIT_SET(oplist, it.tree->tab[it.index].data, data); \
|
||||
@@ -521,7 +521,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _move_down)(it_t pos, type *data) { \
|
||||
it_t it = M_F(name, _insert_down_raw)(pos); \
|
||||
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
|
||||
@@ -529,7 +529,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_child_raw)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
/* Insert a node as a child of another, making the current childreen \
|
||||
@@ -550,7 +550,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_child)(it_t pos, type const data) { \
|
||||
it_t it = M_F(name, _insert_child_raw)(pos); \
|
||||
M_CALL_INIT_SET(oplist, it.tree->tab[it.index].data, data); \
|
||||
@@ -558,7 +558,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _move_child)(it_t pos, type *data) { \
|
||||
it_t it = M_F(name, _insert_child_raw)(pos); \
|
||||
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
|
||||
@@ -566,7 +566,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_left_raw)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
M_ASSERT(it.index != it.tree->root_index); \
|
||||
@@ -590,7 +590,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_left)(it_t pos, type const data) { \
|
||||
it_t it = M_F(name, _insert_left_raw)(pos); \
|
||||
M_CALL_INIT_SET(oplist, it.tree->tab[it.index].data, data); \
|
||||
@@ -598,7 +598,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _move_left)(it_t pos, type *data) { \
|
||||
it_t it = M_F(name, _insert_left_raw)(pos); \
|
||||
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
|
||||
@@ -606,7 +606,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_right_raw)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
M_ASSERT(it.index != it.tree->root_index); \
|
||||
@@ -624,7 +624,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _insert_right)(it_t pos, type const data) { \
|
||||
it_t it = M_F(name, _insert_right_raw)(pos); \
|
||||
M_CALL_INIT_SET(oplist, it.tree->tab[it.index].data, data); \
|
||||
@@ -632,7 +632,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _move_right)(it_t pos, type *data) { \
|
||||
it_t it = M_F(name, _insert_right_raw)(pos); \
|
||||
M_DO_INIT_MOVE(oplist, it.tree->tab[it.index].data, *data); \
|
||||
@@ -640,7 +640,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_up)(it_t *it) { \
|
||||
M_ASSERT(it != NULL); \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
@@ -653,7 +653,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_down)(it_t *it) { \
|
||||
M_ASSERT(it != NULL); \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
@@ -666,7 +666,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_left)(it_t *it) { \
|
||||
M_ASSERT(it != NULL); \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
@@ -679,7 +679,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_right)(it_t *it) { \
|
||||
M_ASSERT(it != NULL); \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
@@ -692,26 +692,26 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _root_p)(const it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
return it.tree->tab[it.index].parent == M_TR33_ROOT_NODE; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _node_p)(const it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
return it.tree->tab[it.index].child != M_TR33_NO_NODE; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _leaf_p)(const it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
return it.tree->tab[it.index].child == M_TR33_NO_NODE; \
|
||||
} \
|
||||
\
|
||||
/* Compute the degree of a node in linear time */ \
|
||||
static inline int32_t \
|
||||
M_INLINE int32_t \
|
||||
M_F(name, _degree)(const it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
int32_t ret = 0; \
|
||||
@@ -724,7 +724,7 @@ typedef int32_t m_tr33_index_t;
|
||||
} \
|
||||
\
|
||||
/* Compute the depth of a node in linear time */ \
|
||||
static inline int32_t \
|
||||
M_INLINE int32_t \
|
||||
M_F(name, _depth)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
int32_t ret = 0; \
|
||||
@@ -736,13 +736,13 @@ typedef int32_t m_tr33_index_t;
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static inline struct M_F(name, _s) * \
|
||||
M_INLINE struct M_F(name, _s) * \
|
||||
M_F(name, _tree)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, false); \
|
||||
return it.tree; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap_at)(it_t it1, it_t it2, bool swapChild) { \
|
||||
M_ASSUME(it1.tree == it2.tree); \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
@@ -823,7 +823,7 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_IT_CONTRACT(it2, true); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
M_INLINE type * \
|
||||
M_F(name, _unlink)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
m_tr33_index_t parent, child, left, right, child_r; \
|
||||
@@ -884,7 +884,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return &it.tree->tab[it.index].data; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _remove)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, false); \
|
||||
if (M_UNLIKELY(it.index < 0)) { return false; } \
|
||||
@@ -895,7 +895,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the parent then the children (uses with _it) */ \
|
||||
/* pre-order walk */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next)(it_t *it) { \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
/* First go down, if impossible go right */ \
|
||||
@@ -915,7 +915,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the children then the parent */ \
|
||||
/* post-order walk */ \
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _it_post)(tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
it_t it; \
|
||||
@@ -929,7 +929,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the children then the parent (uses with _it_post) */ \
|
||||
/* post-order walk */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next_post)(it_t *it) { \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
/* First go right */ \
|
||||
@@ -947,7 +947,7 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_IT_CONTRACT(*it, false); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _it_equal_p)(it_t it1, it_t it2) { \
|
||||
M_TR33_IT_CONTRACT(it1, false); \
|
||||
M_TR33_IT_CONTRACT(it2, false); \
|
||||
@@ -956,7 +956,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the parent, then the children */ \
|
||||
/* post-order walk */ \
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _it_subpre)(it_t it) { \
|
||||
/* Nothing to do as it is already on the parent! */ \
|
||||
return it; \
|
||||
@@ -964,7 +964,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan the nodes of it_ref, first the parent then the children */ \
|
||||
/* pre-order walk */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next_subpre)(it_t *it, it_t it_ref) { \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
M_TR33_IT_CONTRACT(it_ref, true); \
|
||||
@@ -985,7 +985,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the children then the parent */ \
|
||||
/* post-order walk */ \
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _it_subpost)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
/* Evaluate child first, so go down to the lowest child */ \
|
||||
@@ -996,7 +996,7 @@ typedef int32_t m_tr33_index_t;
|
||||
\
|
||||
/* Scan all nodes, first the children then the parent (uses with _it_subpost) */ \
|
||||
/* post-order walk */ \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _next_subpost)(it_t *it, it_t ref) { \
|
||||
M_TR33_IT_CONTRACT(*it, true); \
|
||||
M_TR33_IT_CONTRACT(ref, true); \
|
||||
@@ -1018,7 +1018,7 @@ typedef int32_t m_tr33_index_t;
|
||||
assert(b); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _prune)(it_t it) { \
|
||||
M_TR33_IT_CONTRACT(it, true); \
|
||||
/* remove the node, including its childs */ \
|
||||
@@ -1033,7 +1033,7 @@ typedef int32_t m_tr33_index_t;
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_INLINE it_t \
|
||||
M_F(name, _lca)(it_t it1, it_t it2) { \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
M_TR33_IT_CONTRACT(it2, true); \
|
||||
@@ -1062,7 +1062,7 @@ typedef int32_t m_tr33_index_t;
|
||||
return it1; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _graft_child)(it_t it1, const it_t it2) { \
|
||||
M_ASSERT(it1.tree == it2.tree); \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
@@ -1094,7 +1094,7 @@ typedef int32_t m_tr33_index_t;
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(CMP,oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _sort_child)(it_t it0) { \
|
||||
M_TR33_IT_CONTRACT(it0, true); \
|
||||
it_t it1 = it0; \
|
||||
@@ -1122,7 +1122,7 @@ typedef int32_t m_tr33_index_t;
|
||||
|
||||
/* Define the classic extended missing methods of a tree */
|
||||
#define M_TR33_DEF_P4_EXT(name, type, oplist, tree_t, it_t) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_set)(tree_t tree, const tree_t ref) { \
|
||||
tree->size = ref->size; \
|
||||
tree->capacity = ref->capacity; \
|
||||
@@ -1155,14 +1155,14 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_CONTRACT(tree); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _set)(tree_t tree, const tree_t ref) { \
|
||||
/* No optimum, but good enought for present time */ \
|
||||
M_F(name, _clear)(tree); \
|
||||
M_F(name, _init_set)(tree, ref); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(tree_t tree, tree_t ref) { \
|
||||
tree->size = ref->size; \
|
||||
tree->capacity = ref->capacity; \
|
||||
@@ -1175,13 +1175,13 @@ typedef int32_t m_tr33_index_t;
|
||||
ref->tab = NULL; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(tree_t tree, tree_t ref) { \
|
||||
M_F(name, _clear)(tree); \
|
||||
M_F(name, _init_move)(tree, ref); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(tree_t tree1, tree_t tree2) { \
|
||||
M_TR33_CONTRACT(tree1); \
|
||||
M_TR33_CONTRACT(tree2); \
|
||||
@@ -1195,32 +1195,32 @@ typedef int32_t m_tr33_index_t;
|
||||
M_TR33_CONTRACT(tree2); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _size)(const tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
return (size_t) tree->size; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _empty_p)(const tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
return tree->size == 0; \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _capacity)(const tree_t tree) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
return (size_t) tree->capacity; \
|
||||
} \
|
||||
\
|
||||
/* Service not really usefull as the affectation operator works with it */\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _it_set)(it_t *dst, it_t src ){ \
|
||||
*dst = src; \
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _equal_p)(/*const*/ tree_t t1, /*const*/ tree_t t2) { \
|
||||
M_TR33_CONTRACT(t1); \
|
||||
M_TR33_CONTRACT(t2); \
|
||||
@@ -1282,7 +1282,7 @@ typedef int32_t m_tr33_index_t;
|
||||
, /* No EQUAL */ ) \
|
||||
\
|
||||
M_IF_METHOD(HASH, oplist)( \
|
||||
static inline size_t \
|
||||
M_INLINE size_t \
|
||||
M_F(name, _hash)(/* const */ tree_t t1) { \
|
||||
M_HASH_DECL(hash); \
|
||||
for(it_t it = M_F(name, _it)(t1); \
|
||||
@@ -1299,7 +1299,7 @@ typedef int32_t m_tr33_index_t;
|
||||
/* Define the IO methods of a tree */
|
||||
#define M_TR33_DEF_P4_IO(name, type, oplist, tree_t, it_t) \
|
||||
M_IF_METHOD(GET_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _get_str)(string_t str, /*const*/ tree_t tree, bool append) { \
|
||||
(append ? m_string_cat_cstr : m_string_set_cstr) (str, "["); \
|
||||
it_t it = M_F(name, _it)(tree); \
|
||||
@@ -1335,7 +1335,7 @@ M_F(name, _get_str)(string_t str, /*const*/ tree_t tree, bool append) { \
|
||||
, /* No GET_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(PARSE_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _parse_str)(tree_t tree, const char str[], const char **endp) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
int cmd = 0; \
|
||||
@@ -1400,7 +1400,7 @@ exit: \
|
||||
, /* No PARSE_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(OUT_STR, oplist)( \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _out_str)(FILE *f, /*const*/ tree_t tree) { \
|
||||
fputc('[', f); \
|
||||
it_t it = M_F(name, _it)(tree); \
|
||||
@@ -1436,7 +1436,7 @@ M_F(name, _out_str)(FILE *f, /*const*/ tree_t tree) { \
|
||||
, /* No OUT_STR */ ) \
|
||||
\
|
||||
M_IF_METHOD(IN_STR, oplist)( \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_F(name, _in_str)(tree_t tree, FILE *f) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
int cmd = 0; \
|
||||
@@ -1511,7 +1511,7 @@ exit: \
|
||||
|
||||
/* Definition of the emplace_back functions */
|
||||
#define M_TR33_EMPLACE_ROOT_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline M_F(name, _it_ct) \
|
||||
M_INLINE M_F(name, _it_ct) \
|
||||
function_name(name_t tree \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1533,7 +1533,7 @@ exit: \
|
||||
}
|
||||
|
||||
#define M_TR33_EMPLACE_UP_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline name_t \
|
||||
M_INLINE name_t \
|
||||
function_name(name_t pos \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1544,7 +1544,7 @@ exit: \
|
||||
}
|
||||
|
||||
#define M_TR33_EMPLACE_DOWN_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline name_t \
|
||||
M_INLINE name_t \
|
||||
function_name(name_t pos \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1555,7 +1555,7 @@ exit: \
|
||||
}
|
||||
|
||||
#define M_TR33_EMPLACE_CHILD_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline name_t \
|
||||
M_INLINE name_t \
|
||||
function_name(name_t pos \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1566,7 +1566,7 @@ exit: \
|
||||
}
|
||||
|
||||
#define M_TR33_EMPLACE_LEFT_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline name_t \
|
||||
M_INLINE name_t \
|
||||
function_name(name_t pos \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -1577,7 +1577,7 @@ exit: \
|
||||
}
|
||||
|
||||
#define M_TR33_EMPLACE_RIGHT_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline name_t \
|
||||
M_INLINE name_t \
|
||||
function_name(name_t pos \
|
||||
M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \
|
||||
{ \
|
||||
|
||||
@@ -30,11 +30,12 @@
|
||||
|
||||
/*
|
||||
* Select mechanism to use for support of RAII and exception,
|
||||
* so that for each variables defined in M_LET,
|
||||
* their destructor is still called on throwing exceptions.
|
||||
* so that for each variable defined using M_LET,
|
||||
* its destructor is still called when exceptions are thrown.
|
||||
* It is either the C++ try,
|
||||
* it uses a GCC or CLANG extension,
|
||||
* or the standard c compliant way (much slower).
|
||||
* or it uses a GCC or CLANG extension,
|
||||
* or the standard C compliant way (much slower).
|
||||
* The user can override the desired mechanism.
|
||||
*/
|
||||
#ifndef M_USE_TRY_MECHANISM
|
||||
# if defined(__has_extension)
|
||||
@@ -75,11 +76,12 @@
|
||||
* error_code shall be the first argument.
|
||||
* Other arguments are integers or pointers stored in the exception.
|
||||
* error code shall be a constant positive integer.
|
||||
* There is no genericity of the exception data structure itself.
|
||||
*/
|
||||
#define M_THROW(...) do { \
|
||||
M_STATIC_ASSERT(M_RET_ARG1 (__VA_ARGS__) != 0, \
|
||||
M_LIB_NOT_A_CONSTANT_NON_NULL_INTEGER, \
|
||||
"The error code shall be a non null constant"); \
|
||||
"The error code shall be a non null positive constant"); \
|
||||
M_STATIC_ASSERT(M_NARGS (__VA_ARGS__) <= 1+M_USE_MAX_CONTEXT, \
|
||||
M_LIB_TOO_MANY_ARGUMENTS, \
|
||||
"There are too many arguments for an exception."); \
|
||||
@@ -88,7 +90,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Size of the context data that are stored in an exception.
|
||||
* Size of the context data that are stored in an exception data structure.
|
||||
*/
|
||||
#ifndef M_USE_MAX_CONTEXT
|
||||
#define M_USE_MAX_CONTEXT 10
|
||||
@@ -98,9 +100,9 @@
|
||||
* The exception itself.
|
||||
*
|
||||
* It is POD data where every fields can be used by the user.
|
||||
* It has been decided to have only one exception to simplify error
|
||||
* code, and because :
|
||||
* - using generic types is much hard in C to do (still possible)
|
||||
* It has been decided to have only one exception data structure
|
||||
* to simplify error code and because :
|
||||
* - using generic types is much harder in C to do (still possible)
|
||||
* - it will make exceptions more usable for errors which should not
|
||||
* be handled by exceptions.
|
||||
*
|
||||
@@ -306,7 +308,7 @@ typedef struct m_try_s {
|
||||
{ __VA_ARGS__ } } )
|
||||
|
||||
// Copy an exception to another.
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_exception_set(struct m_exception_s *out, const struct m_exception_s *in)
|
||||
{
|
||||
if (in != out) {
|
||||
@@ -357,7 +359,7 @@ extern M_ATTR_NO_RETURN M_ATTR_COLD_FUNCTION void m_throw(const struct m_excepti
|
||||
}
|
||||
|
||||
// Rethrow the error
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_rethrow(void)
|
||||
{
|
||||
M_ASSERT(m_global_error_list != NULL);
|
||||
@@ -366,7 +368,7 @@ m_rethrow(void)
|
||||
|
||||
// Catch the error code associated to the TRY block state
|
||||
// and provide a pointer to the exception (which is a global).
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_catch(m_try_t state, unsigned error_code, const struct m_exception_s **exception)
|
||||
{
|
||||
M_ASSERT(m_global_error_list == state);
|
||||
@@ -383,7 +385,7 @@ m_catch(m_try_t state, unsigned error_code, const struct m_exception_s **excepti
|
||||
}
|
||||
|
||||
// Initialize the state to a TRY state.
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_try_init(m_try_t state)
|
||||
{
|
||||
state->kind = M_STATE_TRY;
|
||||
@@ -395,7 +397,7 @@ m_try_init(m_try_t state)
|
||||
M_LIKELY ((m_try_init(s), m_try_setjmp(((s)->data.buf)) != 1))
|
||||
|
||||
// Disable the current TRY block.
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_try_clear(m_try_t state)
|
||||
{
|
||||
// Even if there is a CATCH block and an unstack of the exception
|
||||
@@ -422,7 +424,7 @@ m_try_clear(m_try_t state)
|
||||
// However we register the position in the stack frame now so that in case of partial initialization
|
||||
// of the object (if the INIT operator of the object calls other INIT operators of composed fields),
|
||||
// since partial initialization will be unstacked naturally by the composing object.
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_try_cb_pre(m_try_t state)
|
||||
{
|
||||
state->kind = M_STATE_CLEAR_CB;
|
||||
@@ -431,7 +433,7 @@ m_try_cb_pre(m_try_t state)
|
||||
}
|
||||
|
||||
// We register the function to call of the initialized object.
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_try_cb_post(m_try_t state, void (M_TRY_FUNC_OPERATOR func)(void*), void *data)
|
||||
{
|
||||
state->data.clear.func = func;
|
||||
@@ -442,14 +444,14 @@ m_try_cb_post(m_try_t state, void (M_TRY_FUNC_OPERATOR func)(void*), void *data)
|
||||
|
||||
// The object will be cleared.
|
||||
// We can pop the stack frame of the errors.
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_try_cb_final(m_try_t state)
|
||||
{
|
||||
m_global_error_list = state->next;
|
||||
}
|
||||
|
||||
// Pre initialization function. Save the stack frame for a longjmp
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_try_jump_pre(m_try_t state)
|
||||
{
|
||||
state->kind = M_STATE_CLEAR_JMPBUF;
|
||||
@@ -458,7 +460,7 @@ m_try_jump_pre(m_try_t state)
|
||||
}
|
||||
|
||||
// Post initialization function. Register the stack frame for a longjmp
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_try_jump_post(m_try_t state)
|
||||
{
|
||||
m_global_error_list = state;
|
||||
@@ -469,7 +471,7 @@ m_try_jump_post(m_try_t state)
|
||||
|
||||
// The object will be cleared.
|
||||
// We can pop the stack frame of the errors.
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_try_jump_final(m_try_t state)
|
||||
{
|
||||
m_global_error_list = state->next;
|
||||
|
||||
@@ -242,40 +242,42 @@ namespace m_lib {
|
||||
|
||||
/* Define the INIT method calling the INIT method for all params */
|
||||
#define M_TUPL3_DEFINE_INIT(name, ...) \
|
||||
static inline void M_F(name, _init)(M_F(name,_ct) my) { \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_FUNC , __VA_ARGS__) \
|
||||
M_INLINE void M_F(name, _init)(M_F(name,_ct) my) { \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_FUNC , __VA_ARGS__) {} \
|
||||
}
|
||||
|
||||
#define M_TUPL3_DEFINE_INIT_FUNC(a) \
|
||||
M_TUPL3_CALL_INIT(a, my -> M_TUPL3_GET_FIELD a );
|
||||
M_CHAIN_OBJ(M_TUPL3_GET_FIELD a, M_TUPL3_GET_OPLIST a, my -> M_TUPL3_GET_FIELD a)
|
||||
|
||||
/* Define the INIT_SET method calling the INIT_SET method for all params */
|
||||
#define M_TUPL3_DEFINE_INIT_SET(name, ...) \
|
||||
static inline void M_F(name, _init_set)(M_F(name,_ct) my , M_F(name,_ct) const org) { \
|
||||
M_INLINE void M_F(name, _init_set)(M_F(name,_ct) my , M_F(name,_ct) const org) { \
|
||||
M_TUPL3_CONTRACT(org); \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_SET_FUNC , __VA_ARGS__) \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_SET_FUNC , __VA_ARGS__) {} \
|
||||
}
|
||||
#define M_TUPL3_DEFINE_INIT_SET_FUNC(a) \
|
||||
M_TUPL3_CALL_INIT_SET(a, my -> M_TUPL3_GET_FIELD a , org -> M_TUPL3_GET_FIELD a );
|
||||
M_CHAIN_OBJ(M_TUPL3_GET_FIELD a, M_TUPL3_GET_OPLIST a, \
|
||||
my -> M_TUPL3_GET_FIELD a , org -> M_TUPL3_GET_FIELD a )
|
||||
|
||||
/* Define the INIT_WITH method calling the INIT_SET method for all params. */
|
||||
#define M_TUPL3_DEFINE_INIT_SET2(name, ...) \
|
||||
static inline void M_F(name, _init_emplace)(M_F(name,_ct) my \
|
||||
M_INLINE void M_F(name, _init_emplace)(M_F(name,_ct) my \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_SET2_PROTO, __VA_ARGS__) \
|
||||
) { \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_SET2_FUNC , __VA_ARGS__) \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_SET2_FUNC , __VA_ARGS__) {} \
|
||||
}
|
||||
|
||||
#define M_TUPL3_DEFINE_INIT_SET2_PROTO(a) \
|
||||
, M_TUPL3_GET_TYPE a const M_TUPL3_GET_FIELD a
|
||||
|
||||
#define M_TUPL3_DEFINE_INIT_SET2_FUNC(a) \
|
||||
M_TUPL3_CALL_INIT_SET(a, my -> M_TUPL3_GET_FIELD a , M_TUPL3_GET_FIELD a );
|
||||
M_CHAIN_OBJ(M_TUPL3_GET_FIELD a, M_TUPL3_GET_OPLIST a, \
|
||||
my -> M_TUPL3_GET_FIELD a , M_TUPL3_GET_FIELD a )
|
||||
|
||||
|
||||
/* Define the SET method calling the SET method for all params. */
|
||||
#define M_TUPL3_DEFINE_SET(name, ...) \
|
||||
static inline void M_F(name, _set)(M_F(name,_ct) my , \
|
||||
M_INLINE void M_F(name, _set)(M_F(name,_ct) my , \
|
||||
M_F(name,_ct) const org) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
M_TUPL3_CONTRACT(org); \
|
||||
@@ -288,7 +290,7 @@ namespace m_lib {
|
||||
|
||||
/* Define the SET_WITH method calling the SET method for all params. */
|
||||
#define M_TUPL3_DEFINE_SET2(name, ...) \
|
||||
static inline void M_F(name, _emplace)(M_F(name,_ct) my \
|
||||
M_INLINE void M_F(name, _emplace)(M_F(name,_ct) my \
|
||||
M_MAP(M_TUPL3_DEFINE_SET2_PROTO, __VA_ARGS__) \
|
||||
) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
@@ -303,7 +305,7 @@ namespace m_lib {
|
||||
|
||||
/* Define the CLEAR method calling the CLEAR method for all params. */
|
||||
#define M_TUPL3_DEFINE_CLEAR(name, ...) \
|
||||
static inline void M_F(name, _clear)(M_F(name,_ct) my) { \
|
||||
M_INLINE void M_F(name, _clear)(M_F(name,_ct) my) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
M_MAP(M_TUPL3_DEFINE_CLEAR_FUNC , __VA_ARGS__) \
|
||||
}
|
||||
@@ -317,18 +319,18 @@ namespace m_lib {
|
||||
M_MAP3(M_TUPL3_DEFINE_GETTER_FIELD_PROTO, name, __VA_ARGS__)
|
||||
|
||||
#define M_TUPL3_DEFINE_GETTER_FIELD_PROTO(name, num, a) \
|
||||
static inline M_TUPL3_GET_TYPE a * M_C3(name, _get_at_, M_TUPL3_GET_FIELD a) \
|
||||
M_INLINE M_TUPL3_GET_TYPE a * M_C3(name, _get_at_, M_TUPL3_GET_FIELD a) \
|
||||
(M_F(name,_ct) my) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
return &(my->M_TUPL3_GET_FIELD a); \
|
||||
} \
|
||||
static inline M_TUPL3_GET_TYPE a const * M_C3(name, _cget_at_, M_TUPL3_GET_FIELD a) \
|
||||
M_INLINE M_TUPL3_GET_TYPE a const * M_C3(name, _cget_at_, M_TUPL3_GET_FIELD a) \
|
||||
(M_F(name,_ct) const my) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
return &(my->M_TUPL3_GET_FIELD a); \
|
||||
} \
|
||||
/* Same but uses numerical index for accessing the field (internal) */ \
|
||||
static inline M_TUPL3_GET_TYPE a * M_C4(m_tupl3_, name, _get_at_, num) \
|
||||
M_INLINE M_TUPL3_GET_TYPE a * M_C4(m_tupl3_, name, _get_at_, num) \
|
||||
(M_F(name,_ct) my) { \
|
||||
return &(my->M_TUPL3_GET_FIELD a); \
|
||||
} \
|
||||
@@ -339,7 +341,7 @@ namespace m_lib {
|
||||
M_MAP2(M_TUPL3_DEFINE_SETTER_FIELD_PROTO, name, __VA_ARGS__)
|
||||
|
||||
#define M_TUPL3_DEFINE_SETTER_FIELD_PROTO(name, a) \
|
||||
static inline void M_C3(name, _set_, M_TUPL3_GET_FIELD a) \
|
||||
M_INLINE void M_C3(name, _set_, M_TUPL3_GET_FIELD a) \
|
||||
(M_F(name,_ct) my, M_TUPL3_GET_TYPE a const M_TUPL3_GET_FIELD a) { \
|
||||
M_TUPL3_CONTRACT(my); \
|
||||
M_TUPL3_CALL_SET(a, my ->M_TUPL3_GET_FIELD a, M_TUPL3_GET_FIELD a); \
|
||||
@@ -348,7 +350,7 @@ namespace m_lib {
|
||||
|
||||
/* Define the CMP method by calling CMP methods for all params. */
|
||||
#define M_TUPL3_DEFINE_CMP(name, ...) \
|
||||
static inline int M_F(name, _cmp)(M_F(name,_ct) const e1 , \
|
||||
M_INLINE int M_F(name, _cmp)(M_F(name,_ct) const e1 , \
|
||||
M_F(name,_ct) const e2) { \
|
||||
int i; \
|
||||
M_TUPL3_CONTRACT(e1); \
|
||||
@@ -369,7 +371,7 @@ namespace m_lib {
|
||||
FIXME: All oplists shall define the CMP operator or at least one?
|
||||
*/
|
||||
#define M_TUPL3_DEFINE_CMP_ORDER(name, ...) \
|
||||
static inline int M_F(name, _cmp_order)(M_F(name,_ct) const e1 , \
|
||||
M_INLINE int M_F(name, _cmp_order)(M_F(name,_ct) const e1 , \
|
||||
M_F(name,_ct) const e2, \
|
||||
const int order[]) { \
|
||||
int i, r; \
|
||||
@@ -403,7 +405,7 @@ namespace m_lib {
|
||||
)
|
||||
|
||||
#define M_TUPL3_DEFINE_CMP_FIELD_FUNC(name, field, func_cmp, oplist) \
|
||||
static inline int M_C3(name, _cmp_, field)(M_F(name,_ct) const e1 , \
|
||||
M_INLINE int M_C3(name, _cmp_, field)(M_F(name,_ct) const e1 , \
|
||||
M_F(name,_ct) const e2) { \
|
||||
M_TUPL3_CONTRACT(e1); \
|
||||
M_TUPL3_CONTRACT(e2); \
|
||||
@@ -413,7 +415,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a EQUAL method by calling the EQUAL methods for all params */
|
||||
#define M_TUPL3_DEFINE_EQUAL(name, ...) \
|
||||
static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
|
||||
M_INLINE bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
|
||||
M_F(name,_ct) const e2) { \
|
||||
bool b; \
|
||||
M_TUPL3_CONTRACT(e1); \
|
||||
@@ -431,7 +433,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a HASH method by calling the HASH methods for all params */
|
||||
#define M_TUPL3_DEFINE_HASH(name, ...) \
|
||||
static inline size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
|
||||
M_INLINE size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
|
||||
M_TUPL3_CONTRACT(e1); \
|
||||
M_HASH_DECL(hash); \
|
||||
M_MAP(M_TUPL3_DEFINE_HASH_FUNC_P0, __VA_ARGS__) \
|
||||
@@ -446,7 +448,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a GET_STR method by calling the GET_STR methods for all params */
|
||||
#define M_TUPL3_DEFINE_GET_STR(name, ...) \
|
||||
static inline void M_F(name, _get_str)(m_string_t str, \
|
||||
M_INLINE void M_F(name, _get_str)(m_string_t str, \
|
||||
M_F(name,_ct) const el, \
|
||||
bool append) { \
|
||||
bool comma = false; \
|
||||
@@ -465,7 +467,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a OUT_STR method by calling the OUT_STR methods for all params */
|
||||
#define M_TUPL3_DEFINE_OUT_STR(name, ...) \
|
||||
static inline void M_F(name, _out_str)(FILE *f, \
|
||||
M_INLINE void M_F(name, _out_str)(FILE *f, \
|
||||
M_F(name,_ct) const el) { \
|
||||
bool comma = false; \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
@@ -483,7 +485,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a IN_STR method by calling the IN_STR methods for all params */
|
||||
#define M_TUPL3_DEFINE_IN_STR(name, ...) \
|
||||
static inline bool M_F(name, _in_str)(M_F(name,_ct) el, FILE *f) { \
|
||||
M_INLINE bool M_F(name, _in_str)(M_F(name,_ct) el, FILE *f) { \
|
||||
bool comma = false; \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
M_ASSERT (f != NULL); \
|
||||
@@ -506,7 +508,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a PARSE_STR method by calling the PARSE_STR methods for all params */
|
||||
#define M_TUPL3_DEFINE_PARSE_STR(name, ...) \
|
||||
static inline bool M_F(name, _parse_str)(M_F(name,_ct) el, \
|
||||
M_INLINE bool M_F(name, _parse_str)(M_F(name,_ct) el, \
|
||||
const char str[], \
|
||||
const char **endptr) { \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
@@ -540,7 +542,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a OUT_SERIAL method by calling the OUT_SERIAL methods for all params */
|
||||
#define M_TUPL3_DEFINE_OUT_SERIAL(name, ...) \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, \
|
||||
M_F(name,_ct) const el) { \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
@@ -567,7 +569,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a IN_SERIAL method by calling the IN_SERIAL methods for all params */
|
||||
#define M_TUPL3_DEFINE_IN_SERIAL(name, ...) \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(M_F(name,_ct) el, m_serial_read_t f) { \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
M_ASSERT (f != NULL && f->m_interface != NULL); \
|
||||
@@ -598,9 +600,10 @@ namespace m_lib {
|
||||
break; \
|
||||
|
||||
|
||||
/* Define a INIT_MOVE method by calling the INIT_MOVE methods for all params */
|
||||
/* Define a INIT_MOVE method by calling the INIT_MOVE methods for all params
|
||||
INIT_MOVE cannot fail and cannot throw any exception */
|
||||
#define M_TUPL3_DEFINE_INIT_MOVE(name, ...) \
|
||||
static inline void M_F(name, _init_move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_INLINE void M_F(name, _init_move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
M_MAP(M_TUPL3_DEFINE_INIT_MOVE_FUNC , __VA_ARGS__) \
|
||||
}
|
||||
@@ -611,7 +614,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a MOVE method by calling the MOVE methods for all params */
|
||||
#define M_TUPL3_DEFINE_MOVE(name, ...) \
|
||||
static inline void M_F(name, _move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_INLINE void M_F(name, _move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_TUPL3_CONTRACT(el); \
|
||||
M_MAP(M_TUPL3_DEFINE_MOVE_FUNC , __VA_ARGS__) \
|
||||
}
|
||||
@@ -622,7 +625,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a SWAP method by calling the SWAP methods for all params */
|
||||
#define M_TUPL3_DEFINE_SWAP(name, ...) \
|
||||
static inline void M_F(name, _swap)(M_F(name,_ct) el1, M_F(name,_ct) el2) { \
|
||||
M_INLINE void M_F(name, _swap)(M_F(name,_ct) el1, M_F(name,_ct) el2) { \
|
||||
M_TUPL3_CONTRACT(el1); \
|
||||
M_TUPL3_CONTRACT(el2); \
|
||||
M_MAP(M_TUPL3_DEFINE_SWAP_FUNC , __VA_ARGS__) \
|
||||
@@ -634,7 +637,7 @@ namespace m_lib {
|
||||
|
||||
/* Define a RESET method by calling the RESET methods for all params */
|
||||
#define M_TUPL3_DEFINE_RESET(name, ...) \
|
||||
static inline void M_F(name, _reset)(M_F(name,_ct) el1) { \
|
||||
M_INLINE void M_F(name, _reset)(M_F(name,_ct) el1) { \
|
||||
M_TUPL3_CONTRACT(el1); \
|
||||
M_MAP(M_TUPL3_DEFINE_RESET_FUNC , __VA_ARGS__) \
|
||||
} \
|
||||
@@ -742,9 +745,6 @@ namespace m_lib {
|
||||
M_IF_METHOD_ALL(MOVE, __VA_ARGS__)(MOVE(M_F(name, _move)),), \
|
||||
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_F(name, _swap)),), \
|
||||
M_IF_METHOD_ALL(RESET, __VA_ARGS__)(RESET(M_F(name, _reset)),), \
|
||||
M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
EMPLACE_TYPE( ( M_REDUCE2(M_TUPL3_OPLIST_SUBTYPE, M_ID, name, M_SEQ(1, M_NARGS(__VA_ARGS__))) ) ) \
|
||||
)
|
||||
|
||||
|
||||
+27
-30
@@ -219,14 +219,14 @@
|
||||
|
||||
/* Define the INIT function. Init the variant to empty */
|
||||
#define M_VAR1ANT_DEFINE_INIT(name, ...) \
|
||||
static inline void M_F(name, _init)(M_F(name,_ct) my) { \
|
||||
M_INLINE void M_F(name, _init)(M_F(name,_ct) my) { \
|
||||
my->type = M_F(name, _EMPTY); \
|
||||
}
|
||||
|
||||
|
||||
/* Define the INIT_SET function. */
|
||||
#define M_VAR1ANT_DEFINE_INIT_SET(name, ...) \
|
||||
static inline void M_F(name, _init_set)(M_F(name,_ct) my , \
|
||||
M_INLINE void M_F(name, _init_set)(M_F(name,_ct) my , \
|
||||
M_F(name,_ct) const org) { \
|
||||
M_VAR1ANT_CONTRACT(name, org); \
|
||||
my->type = org->type; \
|
||||
@@ -246,7 +246,7 @@
|
||||
|
||||
/* Define the SET function. */
|
||||
#define M_VAR1ANT_DEFINE_SET(name, ...) \
|
||||
static inline void M_F(name, _set)(M_F(name,_ct) my , \
|
||||
M_INLINE void M_F(name, _set)(M_F(name,_ct) my , \
|
||||
M_F(name,_ct) const org) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
M_VAR1ANT_CONTRACT(name, org); \
|
||||
@@ -273,7 +273,7 @@
|
||||
|
||||
/* Define the CLEAR function. */
|
||||
#define M_VAR1ANT_DEFINE_CLEAR(name, ...) \
|
||||
static inline void M_F(name, _clear)(M_F(name,_ct) my) { \
|
||||
M_INLINE void M_F(name, _clear)(M_F(name,_ct) my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
switch (my->type) { \
|
||||
M_MAP2(M_VAR1ANT_DEFINE_CLEAR_FUNC, name, __VA_ARGS__) \
|
||||
@@ -291,11 +291,11 @@
|
||||
|
||||
/* Define the TEST_P function. */
|
||||
#define M_VAR1ANT_DEFINE_TEST_P(name, ...) \
|
||||
static inline bool M_F(name, _empty_p)(M_F(name,_ct) const my) { \
|
||||
M_INLINE bool M_F(name, _empty_p)(M_F(name,_ct) const my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
return my->type == M_F(name, _EMPTY); \
|
||||
} \
|
||||
static inline enum M_F(name, _enum) \
|
||||
M_INLINE enum M_F(name, _enum) \
|
||||
M_F(name, _type)(M_F(name,_ct) my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
return my->type; \
|
||||
@@ -303,7 +303,7 @@
|
||||
M_MAP2(M_VAR1ANT_DEFINE_TEST_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_TEST_FUNC(name, a) \
|
||||
static inline bool \
|
||||
M_INLINE bool \
|
||||
M_C4(name, _, M_VAR1ANT_GET_FIELD a, _p)(M_F(name,_ct) const my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
return my->type == M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
|
||||
@@ -315,7 +315,7 @@
|
||||
M_MAP2(M_VAR1ANT_DEFINE_INIT_FIELD_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_INIT_FIELD_FUNC(name, a) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _init_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my) { \
|
||||
/* Reinit variable with the given value */ \
|
||||
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
|
||||
@@ -328,7 +328,7 @@
|
||||
M_MAP2(M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_INIT_SETTER_FIELD_FUNC(name, a) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _init_set_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
|
||||
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
|
||||
my->type = M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value); \
|
||||
@@ -342,7 +342,7 @@
|
||||
M_MAP2(M_VAR1ANT_DEFINE_SETTER_FIELD_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_SETTER_FIELD_FUNC(name, a) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _set_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
|
||||
M_VAR1ANT_GET_TYPE a const M_VAR1ANT_GET_FIELD a ) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
@@ -364,7 +364,7 @@
|
||||
M_MAP2(M_VAR1ANT_DEFINE_GETTER_FIELD_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_GETTER_FIELD_FUNC(name, a) \
|
||||
static inline M_VAR1ANT_GET_TYPE a * \
|
||||
M_INLINE M_VAR1ANT_GET_TYPE a * \
|
||||
M_C3(name, _get_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
|
||||
@@ -373,7 +373,7 @@
|
||||
return &my -> value . M_VAR1ANT_GET_FIELD a; \
|
||||
} \
|
||||
\
|
||||
static inline M_VAR1ANT_GET_TYPE a const * \
|
||||
M_INLINE M_VAR1ANT_GET_TYPE a const * \
|
||||
M_C3(name, _cget_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) const my) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
if (my->type != M_C4(name, _, M_VAR1ANT_GET_FIELD a, _value) ) { \
|
||||
@@ -397,7 +397,7 @@
|
||||
M_EMPLACE_QUEUE_DEF( (name, M_VAR1ANT_GET_FIELD a), M_F(name,_ct), M_C3(name, _emplace_, M_VAR1ANT_GET_FIELD a), M_VAR1ANT_GET_OPLIST a, M_VAR1ANT_DEFINE_EMPLACE_DEF)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_INIT_EMPLACE_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t my \
|
||||
M_EMPLACE_LIST_TYPE_VAR(ab, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -406,7 +406,7 @@ static inline void \
|
||||
} \
|
||||
|
||||
#define M_VAR1ANT_DEFINE_EMPLACE_DEF(name, name_t, function_name, oplist, init_func, exp_emplace_type) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
function_name(name_t my \
|
||||
M_EMPLACE_LIST_TYPE_VAR(ab, exp_emplace_type) ) \
|
||||
{ \
|
||||
@@ -418,7 +418,7 @@ static inline void \
|
||||
|
||||
/* Define the EQUAL_P function. */
|
||||
#define M_VAR1ANT_DEFINE_EQUAL(name, ...) \
|
||||
static inline bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
|
||||
M_INLINE bool M_F(name, _equal_p)(M_F(name,_ct) const e1 , \
|
||||
M_F(name,_ct) const e2) { \
|
||||
bool b; \
|
||||
M_VAR1ANT_CONTRACT(name, e1); \
|
||||
@@ -442,7 +442,7 @@ static inline void \
|
||||
|
||||
/* Define the HASH function. */
|
||||
#define M_VAR1ANT_DEFINE_HASH(name, ...) \
|
||||
static inline size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
|
||||
M_INLINE size_t M_F(name, _hash)(M_F(name,_ct) const e1) { \
|
||||
M_VAR1ANT_CONTRACT(name, e1); \
|
||||
M_HASH_DECL(hash); \
|
||||
M_HASH_UP (hash, (unsigned int) (e1 -> type)); \
|
||||
@@ -462,7 +462,7 @@ static inline void \
|
||||
|
||||
/* Define the INIT_MOVE function. */
|
||||
#define M_VAR1ANT_DEFINE_INIT_MOVE(name, ...) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _init_move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_VAR1ANT_CONTRACT(name, org); \
|
||||
el -> type = org -> type; \
|
||||
@@ -486,7 +486,7 @@ static inline void \
|
||||
It can be optimized if both types are the same.
|
||||
*/
|
||||
#define M_VAR1ANT_DEFINE_MOVE(name, ...) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _move)(M_F(name,_ct) el, M_F(name,_ct) org) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
M_VAR1ANT_CONTRACT(name, org); \
|
||||
@@ -500,7 +500,7 @@ static inline void \
|
||||
M_MAP2(M_VAR1ANT_DEFINE_MOVER_FUNC, name, __VA_ARGS__)
|
||||
|
||||
#define M_VAR1ANT_DEFINE_MOVER_FUNC(name, a) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(name, _move_, M_VAR1ANT_GET_FIELD a)(M_F(name,_ct) my, \
|
||||
M_VAR1ANT_GET_TYPE a M_VAR1ANT_GET_FIELD a ) { \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
@@ -514,7 +514,7 @@ static inline void \
|
||||
|
||||
/* Define the SWAP function */
|
||||
#define M_VAR1ANT_DEFINE_SWAP(name, ...) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_F(name, _swap)(M_F(name,_ct) el1, M_F(name,_ct) el2) { \
|
||||
M_VAR1ANT_CONTRACT(name, el1); \
|
||||
M_VAR1ANT_CONTRACT(name, el2); \
|
||||
@@ -550,7 +550,7 @@ static inline void \
|
||||
|
||||
/* Define the GET_STR function */
|
||||
#define M_VAR1ANT_DEFINE_GET_STR(name, ...) \
|
||||
static inline void M_F(name, _get_str)(m_string_t str, \
|
||||
M_INLINE void M_F(name, _get_str)(m_string_t str, \
|
||||
M_F(name,_ct) const el, \
|
||||
bool append) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
@@ -574,7 +574,7 @@ static inline void \
|
||||
|
||||
/* Define the PARSE_STR function */
|
||||
#define M_VAR1ANT_DEFINE_PARSE_STR(name, ...) \
|
||||
static inline bool M_F(name, _parse_str)(M_F(name,_ct) el, \
|
||||
M_INLINE bool M_F(name, _parse_str)(M_F(name,_ct) el, \
|
||||
const char str[], \
|
||||
const char **endp) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
@@ -617,7 +617,7 @@ static inline void \
|
||||
|
||||
/* Define the OUT_STR function */
|
||||
#define M_VAR1ANT_DEFINE_OUT_STR(name, ...) \
|
||||
static inline void M_F(name, _out_str)(FILE *f, \
|
||||
M_INLINE void M_F(name, _out_str)(FILE *f, \
|
||||
M_F(name,_ct) const el) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
M_ASSERT (f != NULL); \
|
||||
@@ -638,7 +638,7 @@ static inline void \
|
||||
|
||||
/* Define the IN_STR function */
|
||||
#define M_VAR1ANT_DEFINE_IN_STR(name, ...) \
|
||||
static inline bool M_F(name, _in_str)(M_F(name,_ct) el, \
|
||||
M_INLINE bool M_F(name, _in_str)(M_F(name,_ct) el, \
|
||||
FILE *f) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
M_ASSERT (f != NULL); \
|
||||
@@ -680,7 +680,7 @@ static inline void \
|
||||
|
||||
/* Define the OUT_SERIAL function */
|
||||
#define M_VAR1ANT_DEFINE_OUT_SERIAL(name, ...) \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _out_serial)(m_serial_write_t f, \
|
||||
M_F(name,_ct) const el) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
@@ -711,7 +711,7 @@ static inline void \
|
||||
|
||||
/* Define the IN_SERIAL function */
|
||||
#define M_VAR1ANT_DEFINE_IN_SERIAL(name, ...) \
|
||||
static inline m_serial_return_code_t \
|
||||
M_INLINE m_serial_return_code_t \
|
||||
M_F(name, _in_serial)(M_F(name,_ct) el, \
|
||||
m_serial_read_t f) { \
|
||||
M_VAR1ANT_CONTRACT(name, el); \
|
||||
@@ -745,7 +745,7 @@ static inline void \
|
||||
|
||||
/* Define the RESET function */
|
||||
#define M_VAR1ANT_DEFINE_RESET_FUNC(name, ...) \
|
||||
static inline void M_F(name, _reset)(M_F(name,_ct) my) \
|
||||
M_INLINE void M_F(name, _reset)(M_F(name,_ct) my) \
|
||||
{ \
|
||||
M_VAR1ANT_CONTRACT(name, my); \
|
||||
M_F(name, _clear)(my); \
|
||||
@@ -787,9 +787,6 @@ static inline void \
|
||||
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(INIT_MOVE(M_F(name, _init_move)),), \
|
||||
M_IF_METHOD_ALL(INIT_MOVE, __VA_ARGS__)(MOVE(M_F(name, _move)),), \
|
||||
M_IF_METHOD_ALL(SWAP, __VA_ARGS__)(SWAP(M_F(name, _swap)),), \
|
||||
M_IF_METHOD(NEW, M_RET_ARG1(__VA_ARGS__,))(NEW(M_DELAY2(M_GET_NEW) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
M_IF_METHOD(REALLOC, M_RET_ARG1(__VA_ARGS__,))(REALLOC(M_DELAY2(M_GET_REALLOC) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
M_IF_METHOD(DEL, M_RET_ARG1(__VA_ARGS__,))(DEL(M_DELAY2(M_GET_DEL) M_RET_ARG1(__VA_ARGS__,)),), \
|
||||
)
|
||||
|
||||
|
||||
|
||||
+21
-21
@@ -188,11 +188,11 @@ typedef struct m_worker_sync_s {
|
||||
input is (fieldname, type) or (fieldname, type, oplist)
|
||||
Output shall be : M_OPEXTEND(M_GLOBAL_OPLIST_OR_DEF(type_or_oplist)(), TYPE(type)) / M_OPEXTEND(oplist, TYPE(type))
|
||||
*/
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0(...) M_SUFFIX_FUNCTION_BY_NARGS(M_WORK3R_SPAWN_EXTEND_P0, M_ID __VA_ARGS__) __VA_ARGS__
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0_2(field, type) M_OPEXTEND(M_GLOBAL_OPLIST_OR_DEF(type)(), TYPE(type))
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0_3(field, type, oplist) M_IF_OPLIST(oplist)(M_WORK3R_SPAWN_EXTEND_P0_3_OK, M_WORK3R_SPAWN_EXTEND_P0_3_KO)(field, type, oplist)
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0_3_OK(field, type, oplist) M_OPEXTEND(oplist, TYPE(type))
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0_3_KO(field, type, oplist) \
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0(...) M_BY_NARGS(M_WORK3R_SPAWN_EXTEND_P0, M_ID __VA_ARGS__) __VA_ARGS__
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0__2(field, type) M_OPEXTEND(M_GLOBAL_OPLIST_OR_DEF(type)(), TYPE(type))
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0__3(field, type, oplist) M_IF_OPLIST(oplist)(M_WORK3R_SPAWN_EXTEND_P0__3_OK, M_WORK3R_SPAWN_EXTEND_P0__3_KO)(field, type, oplist)
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0__3_OK(field, type, oplist) M_OPEXTEND(oplist, TYPE(type))
|
||||
#define M_WORK3R_SPAWN_EXTEND_P0__3_KO(field, type, oplist) \
|
||||
M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(M_WORKER_SPAWN_EXTEND): the argument is not a valid oplist: " M_MAP(M_AS_STR, oplist))
|
||||
|
||||
/* Deferred evaluation for the definition,
|
||||
@@ -232,7 +232,7 @@ typedef struct m_worker_sync_s {
|
||||
|
||||
/* Define the callback */
|
||||
#define M_WORK3R_SPAWN_EXTEND_DEF_CALLBACK(name, ...) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_work3r_, name, _clear)(struct M_C3(m_worker_, name, _s) *p) \
|
||||
{ \
|
||||
M_MAP3(M_WORK3R_SPAWN_EXTEND_DEF_CALLBACK_CLEAR, data, __VA_ARGS__) \
|
||||
@@ -240,7 +240,7 @@ typedef struct m_worker_sync_s {
|
||||
M_MEMORY_DEL(p); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C3(m_work3r_, name, _callback)(void *data) \
|
||||
{ \
|
||||
struct M_C3(m_worker_, name, _s) *p = (struct M_C3(m_worker_, name, _s) *) data; \
|
||||
@@ -258,7 +258,7 @@ typedef struct m_worker_sync_s {
|
||||
|
||||
/* Define the emplace like spawn method */
|
||||
#define M_WORK3R_SPAWN_EXTEND_DEF_EMPLACE(name, ...) \
|
||||
static inline void \
|
||||
M_INLINE void \
|
||||
M_C(m_worker_spawn_, name)(m_worker_sync_t block, M_C3(m_worker_, name, _callback_ct) callback, \
|
||||
M_MAP3_C(M_WORK3R_SPAWN_EXTEND_DEF_EMPLACE_FIELD, data, __VA_ARGS__) \
|
||||
) \
|
||||
@@ -299,7 +299,7 @@ typedef struct m_worker_sync_s {
|
||||
/* Return the number of CPU cores available in the system.
|
||||
Works for WINDOWS, MACOS, *BSD, LINUX.
|
||||
*/
|
||||
static inline int
|
||||
M_INLINE int
|
||||
m_work3r_get_cpu_count(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
@@ -332,7 +332,7 @@ m_work3r_get_cpu_count(void)
|
||||
#endif
|
||||
|
||||
/* Execute the registered work order **synchronously** */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_work3r_exec(m_work3r_order_ct *w)
|
||||
{
|
||||
M_ASSERT (w!= NULL && w->block != NULL);
|
||||
@@ -356,7 +356,7 @@ m_work3r_exec(m_work3r_order_ct *w)
|
||||
|
||||
|
||||
/* The worker thread main loop*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_work3r_thread(void *arg)
|
||||
{
|
||||
// Get back the given argument
|
||||
@@ -397,7 +397,7 @@ m_work3r_thread(void *arg)
|
||||
@resetFunc: function to reset the state of a worker between work orders (or NULL if none)
|
||||
@clearFunc: function to clear the state of a worker before terminaning (or NULL if none)
|
||||
*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_init(m_worker_t g, int numWorker, unsigned int extraQueue, void (*resetFunc)(void), void (*clearFunc)(void))
|
||||
{
|
||||
M_ASSERT (numWorker >= -1);
|
||||
@@ -437,7 +437,7 @@ m_worker_init(m_worker_t g, int numWorker, unsigned int extraQueue, void (*reset
|
||||
#define m_worker_init(...) m_worker_init(M_DEFAULT_ARGS(5, (0, 0, NULL, NULL), __VA_ARGS__))
|
||||
|
||||
/* Clear of the worker module (destructor) */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_clear(m_worker_t g)
|
||||
{
|
||||
M_ASSERT (m_work3r_queue_empty_p (g->queue_g));
|
||||
@@ -462,7 +462,7 @@ m_worker_clear(m_worker_t g)
|
||||
|
||||
/* Start a new collaboration between workers of pool 'g'
|
||||
by defining the synchronization point 'block' */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_start(m_worker_sync_t block, m_worker_t g)
|
||||
{
|
||||
atomic_init (&block->num_spawn, 0);
|
||||
@@ -475,7 +475,7 @@ m_worker_start(m_worker_sync_t block, m_worker_t g)
|
||||
The synchronization point is defined a 'block'
|
||||
The work order if composed of the function 'func' and its 'data'
|
||||
*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_spawn(m_worker_sync_t block, void (*func)(void *data), void *data)
|
||||
{
|
||||
const m_work3r_order_ct w = { block, data, func M_WORK3R_EXTRA_ORDER };
|
||||
@@ -493,7 +493,7 @@ m_worker_spawn(m_worker_sync_t block, void (*func)(void *data), void *data)
|
||||
#if M_USE_WORKER_CLANG_BLOCK
|
||||
/* Spawn or not the given work order to workers,
|
||||
or do it ourself if no worker is available */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_work3r_spawn_block(m_worker_sync_t block, void (^func)(void *data), void *data)
|
||||
{
|
||||
const m_work3r_order_ct w = { block, data, NULL, func };
|
||||
@@ -512,7 +512,7 @@ m_work3r_spawn_block(m_worker_sync_t block, void (^func)(void *data), void *data
|
||||
#if M_USE_WORKER_CPP_FUNCTION
|
||||
/* Spawn or not the given work order to workers,
|
||||
or do it ourself if no worker is available */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_work3r_spawn_function(m_worker_sync_t block, std::function<void(void *data)> func, void *data)
|
||||
{
|
||||
const m_work3r_order_ct w = { block, data, NULL, func };
|
||||
@@ -529,7 +529,7 @@ m_work3r_spawn_function(m_worker_sync_t block, std::function<void(void *data)> f
|
||||
#endif
|
||||
|
||||
/* Test if all work orders of the given synchronization point are finished */
|
||||
static inline bool
|
||||
M_INLINE bool
|
||||
m_worker_sync_p(m_worker_sync_t block)
|
||||
{
|
||||
/* If the number of spawns is greated than the number
|
||||
@@ -539,7 +539,7 @@ m_worker_sync_p(m_worker_sync_t block)
|
||||
}
|
||||
|
||||
/* Wait for all work orders of the given synchronization point to be finished */
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_sync(m_worker_sync_t block)
|
||||
{
|
||||
M_WORK3R_DEBUG ("Waiting for thread terminasion.\n");
|
||||
@@ -554,7 +554,7 @@ m_worker_sync(m_worker_sync_t block)
|
||||
}
|
||||
|
||||
/* Flush any work order in the queue ourself if some remains.*/
|
||||
static inline void
|
||||
M_INLINE void
|
||||
m_worker_flush(m_worker_t g)
|
||||
{
|
||||
m_work3r_order_ct w;
|
||||
@@ -566,7 +566,7 @@ m_worker_flush(m_worker_t g)
|
||||
|
||||
|
||||
/* Return the number of workers */
|
||||
static inline size_t
|
||||
M_INLINE size_t
|
||||
m_worker_count(m_worker_t g)
|
||||
{
|
||||
return g->numWorker_g + 1;
|
||||
|
||||
+4
-1
@@ -173,6 +173,9 @@ gene-serial:
|
||||
gene-try:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -O3 -march=native -DNDEBUG -S -std=c11 tgen-try.c && less tgen-try.s
|
||||
|
||||
gene-tuple:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -O3 -march=native -DNDEBUG -S -std=c11 tgen-tuple.c && less tgen-tuple.s
|
||||
|
||||
#####################################################################################################
|
||||
# Coverage
|
||||
#####################################################################################################
|
||||
@@ -253,7 +256,7 @@ sanitize:
|
||||
awk ' printit { print } /END_COVERAGE/ { printit=1}' $< > $<.end.c
|
||||
$(CC) $(CPPFLAGS) -E -DNDEBUG -DWITHIN_COVERAGE $< |grep -v '^#' |awk ' /END_COVERAGE/ { printit=0} printit { print } /START_COVERAGE/ { printit=1 }' |perl -p -e "s/;(?![\"'])/;\n/g ; s/}(?![\"'])/}\n/g ; s/{(?![\"'])/{\n/g" > $<.middle.c
|
||||
cat $<.first.c $<.middle.c $<.end.c > $<.c
|
||||
$(CC) $(CPPFLAGS) -fanalyzer -Wall -W -O2 -g $<.c -o $<.exe 2> `basename $< .c`.analyzer $(LDFLAGS)
|
||||
$(CC) $(CPPFLAGS) -fanalyzer -Wall -W -Wno-analyzer-malloc-leak -O2 -g $<.c -o $<.exe 2> `basename $< .c`.analyzer $(LDFLAGS)
|
||||
$(RM) $<.first.c $<.end.c $<.middle.c $<.c $<.exe
|
||||
|
||||
analyze:
|
||||
|
||||
@@ -201,7 +201,7 @@ static void test_rp_basic(void)
|
||||
{
|
||||
rpdict1_t dict;
|
||||
rpdict1_init(dict);
|
||||
int z;
|
||||
int z = 0;
|
||||
rpdict1_set_at(dict, 2, 3);
|
||||
rpdict1_get_copy(&z, dict, 2);
|
||||
assert (z == 3);
|
||||
|
||||
+28
-2
@@ -570,8 +570,8 @@ static void test_oplist(void)
|
||||
assert (M_ID (M_GET_NAME A5));
|
||||
|
||||
#define A6 (NAME(A6), INIT_WITH(API_1(M_INIT_WITH_NVAR)))
|
||||
#define A6_init_with_1(x) 1
|
||||
#define A6_init_with_2(x, y) 0
|
||||
#define A6_init_with__1(x) 1
|
||||
#define A6_init_with__2(x, y) 0
|
||||
assert (M_ID(M_CALL_INIT_WITH (A6, 0)));
|
||||
assert (M_ID(!M_CALL_INIT_WITH (A6, 0, 0)));
|
||||
}
|
||||
@@ -980,6 +980,31 @@ static void test_generic_api(void)
|
||||
|
||||
}
|
||||
|
||||
static void f_default(int a, int b, int c)
|
||||
{
|
||||
assert( a == 1 );
|
||||
assert( b == 2 );
|
||||
assert( c == 3 );
|
||||
}
|
||||
|
||||
static void test_default(void)
|
||||
{
|
||||
|
||||
#define f11(...) f_default(M_DEFAULT_ARGS(3, (1, 2, 3), __VA_ARGS__))
|
||||
f11(1, 2, 3);
|
||||
f11(1, 2);
|
||||
f11(1);
|
||||
|
||||
#define f12(...) f_default(M_DEFAULT_ARGS(3, (2, 3), __VA_ARGS__))
|
||||
f12(1, 2, 3);
|
||||
f12(1, 2);
|
||||
f12(1);
|
||||
|
||||
#define f13(...) f_default(M_DEFAULT_ARGS(3, (3), __VA_ARGS__))
|
||||
f13(1, 2, 3);
|
||||
f13(1, 2);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_cat();
|
||||
@@ -1006,6 +1031,7 @@ int main(void)
|
||||
test_M_CSTR();
|
||||
test_properties();
|
||||
test_generic_api();
|
||||
test_default();
|
||||
testobj_final_check();
|
||||
exit(0);
|
||||
}
|
||||
@@ -867,9 +867,36 @@ static void test_let_string(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_insert_remove(void)
|
||||
{
|
||||
list_uint_t l;
|
||||
|
||||
list_uint_init(l);
|
||||
list_uint_push_back(l, 1);
|
||||
list_uint_push_back(l, 2);
|
||||
list_uint_push_back(l, 3);
|
||||
|
||||
list_uint_it_t u;
|
||||
unsigned w= 4;
|
||||
list_uint_it(u, l);
|
||||
list_uint_next(u);
|
||||
assert ( list_uint_size(l) == 3);
|
||||
list_uint_insert(l, u, w);
|
||||
assert ( list_uint_size(l) == 4);
|
||||
list_uint_remove(l, u);
|
||||
assert ( list_uint_size(l) == 3);
|
||||
list_uint_insert(l, u, w);
|
||||
assert ( list_uint_size(l) == 4);
|
||||
list_uint_remove(l, u);
|
||||
assert ( list_uint_size(l) == 3);
|
||||
|
||||
list_uint_clear(l);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_uint();
|
||||
test_insert_remove();
|
||||
test_mpz();
|
||||
test_dual_push1();
|
||||
test_dual_it1();
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
ARRAY_DEF(a2, int)
|
||||
#define M_OPL_a2_t() ARRAY_OPLIST(a2, M_BASIC_OPLIST)
|
||||
|
||||
ARRAY_DEF(l2, int)
|
||||
#define M_OPL_l2_t() ARRAY_OPLIST(l2, M_BASIC_OPLIST)
|
||||
LIST_DEF(l2, int)
|
||||
#define M_OPL_l2_t() LIST_OPLIST(l2, M_BASIC_OPLIST)
|
||||
|
||||
DICT_DEF2(d2, string_t, STRING_OPLIST, int, M_BASIC_OPLIST )
|
||||
#define M_OPL_d2_t() DICT_OPLIST(d2, STRING_OPLIST, M_BASIC_OPLIST)
|
||||
@@ -54,7 +54,12 @@ TUPLE_DEF2(my,
|
||||
(vale, a2_t),
|
||||
(valf, v2_t),
|
||||
(valg, l2_t),
|
||||
(valh, d2_t)
|
||||
(valh, d2_t),
|
||||
(vali, unsigned char),
|
||||
(valj, short),
|
||||
(valk, long long),
|
||||
(vall, double),
|
||||
(valm, long double)
|
||||
)
|
||||
#define M_OPL_my_t() TUPLE_OPLIST(my, M_BASIC_OPLIST, M_BASIC_OPLIST, M_BASIC_OPLIST, STRING_OPLIST, M_OPL_a2_t(), M_OPL_v2_t(), M_OPL_l2_t(), M_OPL_d2_t() )
|
||||
|
||||
|
||||
@@ -55,6 +55,37 @@ static void test_utf8_basic(void)
|
||||
string_push_u(s, i);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 1);
|
||||
string_unicode_t j;
|
||||
bool b = string_pop_u(&j, s);
|
||||
assert(b);
|
||||
assert(i== j);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 0);
|
||||
assert(string_size(s) == 0);
|
||||
string_push_u(s, 'A');
|
||||
string_push_u(s, i);
|
||||
size_t len = string_size(s);
|
||||
string_push_u(s, i);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 3);
|
||||
b = string_pop_u(&j, s);
|
||||
assert(b);
|
||||
assert(i== j);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 2);
|
||||
assert(string_size(s) == len);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(b);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 1);
|
||||
assert(string_size(s) == 1);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(b);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 0);
|
||||
assert(string_size(s) == 0);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(!b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +172,60 @@ static void test_utf8_it(void)
|
||||
assert(!string_it_equal_p(it, it2));
|
||||
|
||||
string_clear(s);
|
||||
|
||||
/* Test replacing of unicode */
|
||||
string_init(s);
|
||||
for (string_unicode_t u = 1; u < 0x10ffff; u+=3) {
|
||||
if (u < 0xD800U || u > 0xDFFFU) {
|
||||
for(int c1 = 0 ; c1 <= 3; c1+=2) {
|
||||
for(int c2 = 0 ; c2 <= 20; c2+=5) {
|
||||
const string_unicode_t u_tab[] = { 0, 'B', 300, 45215, 0x10fffe};
|
||||
for(int c3 = 0 ; c3 < 5; c3++) {
|
||||
// Generate string
|
||||
string_reset(s);
|
||||
for(int j = 0; j < c1; j++)
|
||||
string_push_back(s, 'A');
|
||||
string_push_u(s, u);
|
||||
for(int j = 0; j < c2; j++)
|
||||
string_push_back(s, 'C');
|
||||
// Replace iterator in string
|
||||
string_it(it, s);
|
||||
for(int j = 0; j < c1; j++)
|
||||
string_next(it);
|
||||
assert( string_get_cref(it) == u);
|
||||
string_it_set_ref(it, s, u_tab[c3]);
|
||||
if (u_tab[c3] != 0) {
|
||||
assert( string_get_cref(it) == u_tab[c3]);
|
||||
}
|
||||
// Check constructed string
|
||||
string_it(it, s);
|
||||
for(int j = 0; j < c1; j++) {
|
||||
assert( string_get_cref(it) == 'A');
|
||||
string_next(it);
|
||||
}
|
||||
if (u_tab[c3] != 0) {
|
||||
assert( *string_cref(it) == u_tab[c3]);
|
||||
string_next(it);
|
||||
for(int j = 0; j < c2; j++) {
|
||||
assert( string_get_cref(it) == 'C');
|
||||
string_next(it);
|
||||
}
|
||||
}
|
||||
assert(string_end_p(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
string_clear(s);
|
||||
}
|
||||
|
||||
static void call_string_cat_vprintf(string_t s, const char format[], ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
string_cat_vprintf(s, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
static void test0(void)
|
||||
@@ -376,15 +461,27 @@ static void test0(void)
|
||||
string_set_str(s2, "Hello, world! 10 little suns.");
|
||||
assert(string_equal_p(s1, s2) == true);
|
||||
|
||||
string_set_str(s1, "Hello, world!");
|
||||
call_string_cat_vprintf(s1, " %d little %s.", 10, "suns");
|
||||
assert(string_equal_p(s1, s2) == true);
|
||||
|
||||
string_set_str(s1, "X:");
|
||||
string_cat_printf(s1, "");
|
||||
assert(string_equal_str_p(s1, "X:") == true);
|
||||
|
||||
string_set_str(s1, "X:");
|
||||
call_string_cat_vprintf(s1, "");
|
||||
assert(string_equal_str_p(s1, "X:") == true);
|
||||
|
||||
// Illegal format char
|
||||
string_set_str(s1, "X:");
|
||||
string_cat_printf(s1, "%#");
|
||||
assert(string_equal_str_p(s1, "X:") == true);
|
||||
|
||||
string_set_str(s1, "X:");
|
||||
call_string_cat_vprintf(s1, "%#");
|
||||
assert(string_equal_str_p(s1, "X:") == true);
|
||||
|
||||
string_set_str(s1, " \r\n\t HELLO \n\r\t");
|
||||
string_strim(s1);
|
||||
assert (string_cmp_str (s1, "HELLO") == 0);
|
||||
|
||||
@@ -399,9 +399,24 @@ static void test3(void)
|
||||
assert(flow ++ == 0);
|
||||
M_TRY(test1) {
|
||||
assert(flow ++ == 1);
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ >= 13
|
||||
/* Issue with GCC 13. It reports a variable as being not initialized
|
||||
whereas it is obviously initialized.
|
||||
See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109530
|
||||
*/
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
#endif
|
||||
#endif
|
||||
M_DEFER( assert(flow++ == 3) ) {
|
||||
assert(flow ++ == 2);
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ >= 13
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
#endif
|
||||
} M_CATCH(test1, M_ERROR_MEMORY) {
|
||||
assert(0);
|
||||
}
|
||||
@@ -441,6 +456,182 @@ static void test3(void)
|
||||
assert(init == false);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
testobj_t o1;
|
||||
testobj_t o2;
|
||||
int num;
|
||||
} struct_t[1];
|
||||
|
||||
// Pseudo execution counter
|
||||
volatile int g_flow = 0;
|
||||
// Throw execution when g_flow == g_throw
|
||||
volatile int g_throw = 0;
|
||||
|
||||
static void struct_init(struct_t x)
|
||||
{
|
||||
M_CHAIN_INIT(o1, testobj_init(x->o1), testobj_clear(x->o1) )
|
||||
M_CHAIN_INIT(o2, testobj_init(x->o2), testobj_clear(x->o2) ) {
|
||||
x->num = 0;
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void struct_init_set(struct_t x, const struct_t y)
|
||||
{
|
||||
M_CHAIN_INIT(o1, testobj_init_set(x->o1, y->o1), testobj_clear(x->o1) ) {
|
||||
// Throw within the constructor (object partially constructed)
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
M_CHAIN_INIT(o2, testobj_init_set(x->o2, y->o2), testobj_clear(x->o2) ) {
|
||||
x->num = y->num;
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void struct_initb(struct_t x)
|
||||
{
|
||||
M_CHAIN_OBJ(o1, TESTOBJ_OPLIST, x->o1)
|
||||
M_CHAIN_OBJ(o2, TESTOBJ_OPLIST, x->o2)
|
||||
M_CHAIN_OBJ(o3, M_BASIC_OPLIST, x->num) {
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void struct_init_setb(struct_t x, const struct_t y)
|
||||
{
|
||||
M_CHAIN_OBJ(o1, TESTOBJ_OPLIST, x->o1, y->o1) {
|
||||
// Throw within the constructor (object partially constructed)
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
M_CHAIN_OBJ(o2, TESTOBJ_OPLIST, x->o2, y->o2)
|
||||
M_CHAIN_OBJ(o3, M_BASIC_OPLIST, x->num, y->num) {
|
||||
if (++g_flow == g_throw) M_THROW(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void struct_clear(struct_t x)
|
||||
{
|
||||
testobj_clear(x->o1);
|
||||
testobj_clear(x->o2);
|
||||
}
|
||||
|
||||
#define M_OPL_struct_t() M_CLASSIC_OPLIST(struct)
|
||||
|
||||
static void test4a(void)
|
||||
{
|
||||
g_flow = 0;
|
||||
g_throw = 4;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, struct_t) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), struct_t) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 5);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 5;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, struct_t) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), struct_t) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 6);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 2;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, struct_t) {
|
||||
assert(false);
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 3);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 0;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, struct_t) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), struct_t) {
|
||||
assert(++g_flow == 6);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
#define STRUCTB_OPLIST \
|
||||
(INIT(struct_initb), INIT_SET(struct_init_setb), CLEAR(struct_clear), TYPE(struct_t))
|
||||
|
||||
static void test4b(void)
|
||||
{
|
||||
g_flow = 0;
|
||||
g_throw = 4;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, STRUCTB_OPLIST) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), STRUCTB_OPLIST) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 5);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 5;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, STRUCTB_OPLIST) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), STRUCTB_OPLIST) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 6);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 2;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, STRUCTB_OPLIST) {
|
||||
assert(false);
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(++g_flow == 3);
|
||||
}
|
||||
|
||||
g_flow = 0;
|
||||
g_throw = 0;
|
||||
M_TRY(main) {
|
||||
assert(++g_flow == 1);
|
||||
M_LET(a, STRUCTB_OPLIST) {
|
||||
assert(++g_flow == 3);
|
||||
M_LET( (b, a), STRUCTB_OPLIST) {
|
||||
assert(++g_flow == 6);
|
||||
}
|
||||
}
|
||||
} M_CATCH(main, 0) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_final(void)
|
||||
{
|
||||
// Throw without a try block shall raise the M_RAISE_FATAL macro
|
||||
@@ -457,6 +648,8 @@ int main(void)
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4a();
|
||||
test4b();
|
||||
testobj_final_check();
|
||||
test_final();
|
||||
exit(1); // Shall not be reached.
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2023, Patrick Pelissier
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* + Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* + Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "m-try.h"
|
||||
#include "m-tuple.h"
|
||||
#include "m-string.h"
|
||||
|
||||
TUPLE_DEF2( tuple, (name, string_t), (surname, string_t), (value, int))
|
||||
|
||||
void duplicate(tuple_t dst, const tuple_t src)
|
||||
{
|
||||
tuple_init_set(dst, src);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user