Update documentation
This commit is contained in:
1 parent
9f780805f0
commit
a4ff7c71f2
1 file changed
+46
-48
@@ -1,4 +1,4 @@
|
|||||||
M\*LIB: a Generic type-safe Container Library in C language
|
M\*LIB: Generic type-safe Container Library for C language
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
@@ -15,7 +15,7 @@ without erasing type information (typically using void pointers or resorting
|
|||||||
to C macro to access the container).
|
to C macro to access the container).
|
||||||
|
|
||||||
This is an equivalent of the [C++](https://en.wikipedia.org/wiki/C%2B%2B)
|
This is an equivalent of the [C++](https://en.wikipedia.org/wiki/C%2B%2B)
|
||||||
[STL](https://en.wikipedia.org/wiki/Standard_Template_Library) but for standard ISO C99.
|
[Standard Library](https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library) but for standard ISO C99 / C11.
|
||||||
There is not a strict mapping as both the STL and M\*LIB have their exclusive containers:
|
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.
|
See [here](https://github.com/P-p-H-d/mlib/wiki/STL-to-M*LIB-mapping) for details.
|
||||||
|
|
||||||
@@ -30,26 +30,25 @@ There is no dependency (except some other headers of M\*LIB and the LIBC).
|
|||||||
One of M\*LIB's design key is to ensure safety. This is done by multiple means:
|
One of M\*LIB's design key is to ensure safety. This is done by multiple means:
|
||||||
|
|
||||||
* in debug mode, defensive programming is extensively used:
|
* in debug mode, defensive programming is extensively used:
|
||||||
the contracts of the function are checked, ensuring
|
the contracts of the function are checked, ensuring
|
||||||
that the data are not corrupted. For example,
|
that the data are not corrupted. For example,
|
||||||
[Buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) are checked in this mode
|
[Buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) are checked in this mode
|
||||||
through [bound checking](https://en.wikipedia.org/wiki/Bounds_checking)
|
through [bound checking](https://en.wikipedia.org/wiki/Bounds_checking)
|
||||||
or the intrinsic properties of a Red-Black tree are verified.
|
or the intrinsic properties of a Red-Black tree (for example) are verified.
|
||||||
* very few casts are used within the library. Still the library can be used
|
* as few cast as possible are used within the library (as cast are the evil of safety).
|
||||||
with the greatest level of warnings by a C compiler without
|
Still the library can be used with the greatest level of warnings by a C compiler without
|
||||||
any aliasing warning.
|
any aliasing warning.
|
||||||
* the genericity is not done directly by macro, but indirectly by making them
|
* the genericity is not done directly by macro, but indirectly by making them
|
||||||
define inline functions with the proper prototypes: this enables
|
define inline functions with the proper prototypes: this enables
|
||||||
the user calls to have proper warning checks.
|
the user calls to have proper warning checks.
|
||||||
|
|
||||||
Other key designs are:
|
Other key designs are:
|
||||||
|
|
||||||
* do not rewrite the C library and just wrap around it (for example don't rewrite sort but stable sort),
|
* do not rewrite the C library and just wrap around it (for example don't rewrite sort but stable sort),
|
||||||
* do not make users pay the cost of what they don't need.
|
* do not make users pay the cost of what they don't need.
|
||||||
|
|
||||||
Due to the [weak](https://en.wikipedia.org/wiki/Strong_and_weak_typing#Pointers) nature of the C language for pointers,
|
Due to the [weak](https://en.wikipedia.org/wiki/Strong_and_weak_typing#Pointers) nature of the C language for pointers,
|
||||||
[type safe](https://en.wikipedia.org/wiki/Type_safety)
|
[type safe](https://en.wikipedia.org/wiki/Type_safety) means that at least a warning
|
||||||
means that at least a warning
|
|
||||||
is generated by the compiler in case of wrong type passed as
|
is generated by the compiler in case of wrong type passed as
|
||||||
container arguments to the functions.
|
container arguments to the functions.
|
||||||
|
|
||||||
@@ -63,9 +62,8 @@ is one of the fastest generic C library you can find.
|
|||||||
|
|
||||||
M\*LIB uses internally the 'malloc', 'realloc' and 'free' functions to handle
|
M\*LIB uses internally the 'malloc', 'realloc' and 'free' functions to handle
|
||||||
the memory pool. This behavior can be overridden at different level.
|
the memory pool. This behavior can be overridden at different level.
|
||||||
M\*LIB default policy is to abort the
|
M\*LIB default policy is to abort the program if there is a memory error.
|
||||||
program if there is a memory error. However, this behavior
|
However, this behavior can also be customized globally.
|
||||||
can also be customized.
|
|
||||||
|
|
||||||
M\*LIB may use a lot of assertions in its implementation to ensure safety:
|
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.
|
it is highly recommended to properly define NDEBUG for released programs.
|
||||||
@@ -470,7 +468,7 @@ to specify that the function accept as its *first* argument a pointer
|
|||||||
to the type rather than the type itself
|
to the type rather than the type itself
|
||||||
(aka the prototype is init\_func(type `*`) instead of init\_func(type)).
|
(aka the prototype is init\_func(type `*`) instead of init\_func(type)).
|
||||||
If you use the '[1]' trick (see below), you won't need this.
|
If you use the '[1]' trick (see below), you won't need this.
|
||||||
See also the API\_* transformation call below for further transformation
|
See also the API\_\* transformation call below for further transformation
|
||||||
means of the calls.
|
means of the calls.
|
||||||
|
|
||||||
An oplist has no real form from a C language point of view. It is just an abstraction
|
An oplist has no real form from a C language point of view. It is just an abstraction
|
||||||
@@ -572,7 +570,7 @@ Example:
|
|||||||
|
|
||||||
If there is two operations with the same name in an oplist, the left one has the priority. This enables partial overriding.
|
If there is two operations with the same name in an oplist, the left one has the priority. This enables partial overriding.
|
||||||
|
|
||||||
Oplists can be registered globally by defining, for the type 'type', a macro named
|
Oplist can be registered globally by defining, for the type 'type', a macro named
|
||||||
M\_OPL\_ ## type () that expands to the oplist of the type.
|
M\_OPL\_ ## type () that expands to the oplist of the type.
|
||||||
Only type without space in their name can be registered. A typedef of the type
|
Only type without space in their name can be registered. A typedef of the type
|
||||||
can be used instead through. This can simplify a lot OPLIST usage.
|
can be used instead through. This can simplify a lot OPLIST usage.
|
||||||
@@ -611,7 +609,7 @@ An operator OP can be defined, omitted or disabled:
|
|||||||
|
|
||||||
My type is:
|
My type is:
|
||||||
|
|
||||||
* a C boolean: M\_BOOL\_OPLIST (M\_DEFAULT\_OPLIST also works partially),
|
* a C Boolean: M\_BOOL\_OPLIST (M\_DEFAULT\_OPLIST also works partially),
|
||||||
* a C integer or a C float: M\_DEFAULT\_OPLIST (it can also be omitted),
|
* a C integer or a C float: M\_DEFAULT\_OPLIST (it can also be omitted),
|
||||||
* a C enumerate: M\_ENUM\_OPLIST,
|
* a C enumerate: M\_ENUM\_OPLIST,
|
||||||
* a pointer to something (the contained do nothing on the pointed object): M\_PTR\_OPLIST,
|
* a pointer to something (the contained do nothing on the pointed object): M\_PTR\_OPLIST,
|
||||||
@@ -623,7 +621,7 @@ My type is:
|
|||||||
* a M\*LIB container: the OPLIST of the used container,
|
* a M\*LIB container: the OPLIST of the used container,
|
||||||
* other things: you need to provide a custom OPLIST to your type.
|
* other things: you need to provide a custom OPLIST to your type.
|
||||||
|
|
||||||
Note: The precise exported methods of the oplists depend of the version
|
Note: The precise exported methods of the Oplist depend of the version
|
||||||
of the C language used. Typically, in C11 mode, the M\_DEFAULT\_OPLIST
|
of the C language used. Typically, in C11 mode, the M\_DEFAULT\_OPLIST
|
||||||
exports all needed methods to handle generic input/output of int/floats
|
exports all needed methods to handle generic input/output of int/floats
|
||||||
(using _Generic) whereas it is not possible in C99 mode.
|
(using _Generic) whereas it is not possible in C99 mode.
|
||||||
@@ -2198,7 +2196,7 @@ The following methods are automatically and properly created by the previous mac
|
|||||||
|
|
||||||
##### name\_itref\_t
|
##### name\_itref\_t
|
||||||
|
|
||||||
Type of one item referenced in the dictionnary. It is either:
|
Type of one item referenced in the dictionary. It is either:
|
||||||
|
|
||||||
* a structure composed of the key (field key) and the value (field value) if the dict is a map
|
* a structure composed of the key (field key) and the value (field value) if the dict is a map
|
||||||
* or the basic type of the container if the dict is a set.
|
* or the basic type of the container if the dict is a set.
|
||||||
@@ -2365,7 +2363,7 @@ is provided.
|
|||||||
|
|
||||||
#### TUPLE\_OPLIST(name, oplist1[, ...] )
|
#### TUPLE\_OPLIST(name, oplist1[, ...] )
|
||||||
|
|
||||||
Return the oplist of the tuple defined by calling TUPLE\_DEF2 with the given name & the oplists.
|
Return the oplist of the tuple defined by calling TUPLE\_DEF2 with the given name & the Oplist.
|
||||||
|
|
||||||
#### Created methods
|
#### Created methods
|
||||||
|
|
||||||
@@ -2397,19 +2395,19 @@ Set the tuple 'tuple' to the value of 'ref'.
|
|||||||
|
|
||||||
##### void name\_emplace(name\_t tuple, const type1 element1[, ...])
|
##### void name\_emplace(name\_t tuple, const type1 element1[, ...])
|
||||||
|
|
||||||
Set the tuple 'tuple' to the value of the tuple construted with ('element1'[,...]).
|
Set the tuple 'tuple' to the value of the tuple constructed with ('element1'[,...]).
|
||||||
|
|
||||||
##### void name\_init\_move(name\_t tuple, name\_t ref)
|
##### void name\_init\_move(name\_t tuple, name\_t ref)
|
||||||
|
|
||||||
Initialize the tuple 'tuple' (aka constructor) by stealing as many resources from 'ref' as possible.
|
Initialize the tuple 'tuple' (aka constructor) by stealing as many resources from 'ref' as possible.
|
||||||
After-wise 'ref' is cleared.
|
After-wise 'ref' is cleared.
|
||||||
This method is created only if all oplists of the tuple define INIT\_MOVE method.
|
This method is created only if all Oplist of the tuple define INIT\_MOVE method.
|
||||||
|
|
||||||
##### void name\_move(name\_t tuple, name\_t ref)
|
##### void name\_move(name\_t tuple, name\_t ref)
|
||||||
|
|
||||||
Set the tuple 'tuple' by stealing as many resources from 'ref' as possible.
|
Set the tuple 'tuple' by stealing as many resources from 'ref' as possible.
|
||||||
After-wise 'ref' is cleared.
|
After-wise 'ref' is cleared.
|
||||||
This method is created only if all oplists of the tuple define MOVE method.
|
This method is created only if all Oplist of the tuple define MOVE method.
|
||||||
|
|
||||||
##### void name\_clear(name\_t tuple)
|
##### void name\_clear(name\_t tuple)
|
||||||
|
|
||||||
@@ -2433,7 +2431,7 @@ There is as many methods as there are elements.
|
|||||||
##### int name\_cmp(const name\_t tuple1, const name\_t tuple2)
|
##### int name\_cmp(const name\_t tuple1, const name\_t tuple2)
|
||||||
|
|
||||||
Compare 'tuple1' to 'tuple2' using lexicographic order.
|
Compare 'tuple1' to 'tuple2' using lexicographic order.
|
||||||
This method is created only if all oplists of the tuple define CMP method.
|
This method is created only if all Oplist of the tuple define CMP method.
|
||||||
|
|
||||||
##### int name\_cmp\_order(const name\_t tuple1, const name\_t tuple2, const int order[])
|
##### int name\_cmp\_order(const name\_t tuple1, const name\_t tuple2, const int order[])
|
||||||
|
|
||||||
@@ -2442,7 +2440,7 @@ Compare 'tuple1' to 'tuple2' using the given order.
|
|||||||
an order of {1,4,2,0} indicates to compare first the first field,
|
an order of {1,4,2,0} indicates to compare first the first field,
|
||||||
if it is equal, to compare the fourth and so on. The third field is not
|
if it is equal, to compare the fourth and so on. The third field is not
|
||||||
compared. A negative value indicates to revert the comparison.
|
compared. A negative value indicates to revert the comparison.
|
||||||
This method is created only if all oplists of the tuple define CMP method.
|
This method is created only if all Oplist of the tuple define CMP method.
|
||||||
|
|
||||||
##### int name\_cmp\_element1(const name\_t tuple1, const name\_t tuple2)
|
##### int name\_cmp\_element1(const name\_t tuple1, const name\_t tuple2)
|
||||||
|
|
||||||
@@ -2452,13 +2450,13 @@ This method is created only if the oplist of element1 defines the CMP method.
|
|||||||
##### int name\_equal\_p(const name\_t tuple1, const name\_t tuple2)
|
##### int name\_equal\_p(const name\_t tuple1, const name\_t tuple2)
|
||||||
|
|
||||||
Return true if 'tuple1' and 'tuple2' are identical.
|
Return true if 'tuple1' and 'tuple2' are identical.
|
||||||
This method is created only if all oplists of the tuple define EQUAL method.
|
This method is created only if all Oplist of the tuple define EQUAL method.
|
||||||
|
|
||||||
##### void name\_get\_str(string\_t str, const name\_t tuple, bool append)
|
##### void name\_get\_str(string\_t str, const name\_t tuple, bool append)
|
||||||
|
|
||||||
Generate a string representation of the tuple 'tuple' and set 'str' to this representation
|
Generate a string representation of the tuple 'tuple' and set 'str' to this representation
|
||||||
(if 'append' is false) or append 'str' with this representation (if 'append' is true).
|
(if 'append' is false) or append 'str' with this representation (if 'append' is true).
|
||||||
This method is only defined if all oplists define a GET\_STR method.
|
This method is only defined if all Oplist define a GET\_STR method.
|
||||||
|
|
||||||
##### bool name\_parse\_str(name\_t tuple, const char str[], const char **endp)
|
##### bool name\_parse\_str(name\_t tuple, const char str[], const char **endp)
|
||||||
|
|
||||||
@@ -2472,12 +2470,12 @@ decoded by the function.
|
|||||||
##### void name\_out\_str(FILE *file, const name\_t tuple)
|
##### void name\_out\_str(FILE *file, const name\_t tuple)
|
||||||
|
|
||||||
Generate a string representation of the tuple 'tuple' and outputs it into the FILE 'file'.
|
Generate a string representation of the tuple 'tuple' and outputs it into the FILE 'file'.
|
||||||
This method is only defined if all oplists define a OUT\_STR method.
|
This method is only defined if all Oplist define a OUT\_STR method.
|
||||||
|
|
||||||
##### void name\_in\_str(name\_t tuple, FILE *file)
|
##### void name\_in\_str(name\_t tuple, FILE *file)
|
||||||
|
|
||||||
Read from the file 'file' a string representation of a tuple and set 'tuple' to this representation.
|
Read from the file 'file' a string representation of a tuple and set 'tuple' to this representation.
|
||||||
This method is only defined if all oplists define a IN\_STR method.
|
This method is only defined if all Oplist define a IN\_STR method.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2524,7 +2522,7 @@ is provided.
|
|||||||
|
|
||||||
#### VARIANT\_OPLIST(name, oplist1[, ...] )
|
#### VARIANT\_OPLIST(name, oplist1[, ...] )
|
||||||
|
|
||||||
Return the oplist of the variant defined by calling VARIANT\_DEF2 with the given name & the oplists.
|
Return the oplist of the variant defined by calling VARIANT\_DEF2 with the given name & the Oplist.
|
||||||
|
|
||||||
#### Created methods
|
#### Created methods
|
||||||
|
|
||||||
@@ -2553,14 +2551,14 @@ Set the variant 'variant' to the value of 'ref'.
|
|||||||
|
|
||||||
Initialize the variant 'variant' (aka constructor) by stealing as many resources from 'ref' as possible.
|
Initialize the variant 'variant' (aka constructor) by stealing as many resources from 'ref' as possible.
|
||||||
After-wise 'ref' is cleared.
|
After-wise 'ref' is cleared.
|
||||||
This method is created only if all oplists of the variant define INIT\_MOVE method.
|
This method is created only if all Oplist of the variant define INIT\_MOVE method.
|
||||||
|
|
||||||
##### void name\_move(name\_t variant, name\_t ref)
|
##### void name\_move(name\_t variant, name\_t ref)
|
||||||
##### void name\_move\_elementN(name\_t variant, typeN ref)
|
##### void name\_move\_elementN(name\_t variant, typeN ref)
|
||||||
|
|
||||||
Set the variant 'variant' by stealing as many resources from 'ref' as possible.
|
Set the variant 'variant' by stealing as many resources from 'ref' as possible.
|
||||||
After-wise 'ref' is cleared.
|
After-wise 'ref' is cleared.
|
||||||
This method is created only if all oplists of the variant define MOVE method.
|
This method is created only if all Oplist of the variant define MOVE method.
|
||||||
|
|
||||||
##### void name\_clear(name\_t variant)
|
##### void name\_clear(name\_t variant)
|
||||||
|
|
||||||
@@ -4082,7 +4080,7 @@ freed by DEL.
|
|||||||
|
|
||||||
It can be used for statically allocated entities. However, in this case,
|
It can be used for statically allocated entities. However, in this case,
|
||||||
you shall disable the operator NEW & DEL when expanding the oplist
|
you shall disable the operator NEW & DEL when expanding the oplist
|
||||||
so that the CLEAR method doesn't try to free the objectslike this:
|
so that the CLEAR method doesn't try to free the objects like this:
|
||||||
|
|
||||||
(NEW(0), DEL(0))
|
(NEW(0), DEL(0))
|
||||||
|
|
||||||
@@ -4131,7 +4129,7 @@ It initializes the private fields of 'object' handling the shared pointer,
|
|||||||
returning a pointer to the object (but initialized).
|
returning a pointer to the object (but initialized).
|
||||||
|
|
||||||
As a consequence, the shared pointer part of 'object' shall not have been initialized yet.
|
As a consequence, the shared pointer part of 'object' shall not have been initialized yet.
|
||||||
The other part of 'objec' may or may not be initialized before calling this method.
|
The other part of 'object' may or may not be initialized before calling this method.
|
||||||
|
|
||||||
##### name\_t name\_init\_set(name\_t shared)
|
##### name\_t name\_init\_set(name\_t shared)
|
||||||
|
|
||||||
@@ -5123,7 +5121,7 @@ str1 shall be a non empty string.
|
|||||||
##### size\_t string\_replace\_all\_str (string\_t v, const char str1[], const char str2[])
|
##### size\_t string\_replace\_all\_str (string\_t v, const char str1[], const char str2[])
|
||||||
##### size\_t string\_replace\_all (string\_t v, const string\_t str1, const string\_t str2)
|
##### size\_t string\_replace\_all (string\_t v, const string\_t str1, const string\_t str2)
|
||||||
|
|
||||||
Replace in the string 'v' all the occurences of
|
Replace in the string 'v' all the occurrences of
|
||||||
the string 'str1' by the string 'str2'.
|
the string 'str1' by the string 'str2'.
|
||||||
str1 shall be a non empty string.
|
str1 shall be a non empty string.
|
||||||
|
|
||||||
@@ -5778,7 +5776,7 @@ Return the associated method to the given operator within the given oplist.
|
|||||||
|
|
||||||
##### M\_BOOL\_OPLIST
|
##### M\_BOOL\_OPLIST
|
||||||
|
|
||||||
Default oplist for C standard boolean.
|
Default oplist for C standard Boolean.
|
||||||
|
|
||||||
##### M\_DEFAULT\_OPLIST
|
##### M\_DEFAULT\_OPLIST
|
||||||
|
|
||||||
@@ -6008,8 +6006,8 @@ data structures into a format that can be stored or transmitted.
|
|||||||
When the resulting format is reread and translated,
|
When the resulting format is reread and translated,
|
||||||
it creates a semantically identical clone of the original object.
|
it creates a semantically identical clone of the original object.
|
||||||
|
|
||||||
A generic serialization object is an object that takes a C object (boolean, integer, float,
|
A generic serialization object is an object that takes a C object (Boolean, integer, float,
|
||||||
structure, union, pointer, array, list, hashmap, ...) and outputs it into a serialization way through
|
structure, union, pointer, array, list, hash-map, ...) and outputs it into a serialization way through
|
||||||
the following defined interface that defined the format of the serialization and where it is
|
the following defined interface that defined the format of the serialization and where it is
|
||||||
physically output.
|
physically output.
|
||||||
|
|
||||||
@@ -6037,7 +6035,7 @@ The serialization input object is named as m\_serial\_read\_t, defined in m-core
|
|||||||
* m\_interface: a pointer to the constant m\_serial\_read\_interface\_s structure that defines all
|
* m\_interface: a pointer to the constant m\_serial\_read\_interface\_s structure that defines all
|
||||||
methods that operate on this object to parse it. The instance has to be customized for the needs of the
|
methods that operate on this object to parse it. The instance has to be customized for the needs of the
|
||||||
wanted serialization.
|
wanted serialization.
|
||||||
* data: a table of M\_SERIAL\_MAX\_DATA\_SIZE of C types (boolean, integer, size or pointer).
|
* 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 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 defines
|
||||||
@@ -6545,15 +6543,15 @@ to any C compiler (C11 or C99 compliant) or C++ compiler.
|
|||||||
If available, it uses the C11 header stdatomic.h,
|
If available, it uses the C11 header stdatomic.h,
|
||||||
otherwise if the compiler is a C++ compiler,
|
otherwise if the compiler is a C++ compiler,
|
||||||
it uses the header 'atomic' and imports all definition
|
it uses the header 'atomic' and imports all definition
|
||||||
into the global namespace (this is needed because the
|
into the global name space (this is needed because the
|
||||||
C++ standard doesn't support officially the stdatomic header,
|
C++ standard doesn't support officially the stdatomic header,
|
||||||
resulting in broken compilation when building C code with
|
resulting in broken compilation when building C code with
|
||||||
a C++ compiler).
|
a C++ compiler).
|
||||||
|
|
||||||
Otherwise it provides a non-thin emulation of atomic
|
Otherwise it provides a non-thin emulation of atomic
|
||||||
using mutex. This emulation has a known theorical limitation:
|
using mutex. This emulation has a known theoretical limitation:
|
||||||
the mutex are never cleared. There is nothing to do
|
the mutex are never cleared. There is nothing to do
|
||||||
to fix this. In practise, it is not a problem.
|
to fix this. In practice, it is not a problem.
|
||||||
|
|
||||||
|
|
||||||
### M-ALGO
|
### M-ALGO
|
||||||
@@ -7220,9 +7218,9 @@ Clear the serialization object 'serial'.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Licence
|
# License
|
||||||
|
|
||||||
All files of M\*LIB are distributed under the following licence.
|
All files of M\*LIB are distributed under the following license.
|
||||||
|
|
||||||
Copyright (c) 2017-2020, Patrick Pelissier
|
Copyright (c) 2017-2020, Patrick Pelissier
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|||||||
Reference in new issue
Block a user