diff --git a/README.md b/README.md index d54f1155..0138779a 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,19 @@ M\*LIB: Generic type-safe Container Library for C language Overview -------- -M\*LIB (M star lib) is a C library enabling to use **generic and +M\*LIB (M star lib) is a C library enabling to define and use **generic and type safe container** in pure C language, aka handling generic -[containers](https://en.wikipedia.org/wiki/Container_%28abstract_data_type%29). -The objects within the containers can still have proper constructor, destructor -(and other methods): -this is handled by the library. This makes it possible to construct fully +[containers](https://en.wikipedia.org/wiki/Container_%28abstract_data_type%29) in C. +The objects within the containers can be trivial or very complex: +they can have their own constructor, destructor, operators. +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). 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) +but for 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. @@ -23,7 +24,8 @@ M\*LIB is portable to any systems that support [ISO C99](https://en.wikipedia.or Some optional features need at least [ISO C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)). M\*LIB is **only** composed of a set of headers. -There is no C file: you just have to put the header in the search path of your compiler, +There is no C file, and as such, the installation is quite simple: +you just have to put the header in the search path of your compiler, and it will work. There is no dependency (except some other headers of M\*LIB and the LIBC). @@ -35,30 +37,35 @@ One of M\*LIB's design key is to ensure safety. This is done by multiple means: [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. -* as few cast as possible are used within the library (as cast are the evil of safety). + Buffer overflow checks can still be kept in release mode if needed. +* 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 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 test suite itself is run through the multiple sanitizers defined by GCC/CLANG (Address, undefined, leak, thread). + The test suite also includes a comparaison of equivalent behaviors of M\*LIB with the C++ STL using random genetic algorithms. +* static analysis: multiple static analyser (like scan-build or GCC fanalyzer or CodeQL) are run on the generated code, and the results analyzed. 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 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 unfortunate [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) means that at least a warning is generated by the compiler in case of wrong type passed as container arguments to the functions. -M\*LIB is still be quite-efficient: even if the implementation may not always be state -of the art, there is no overhead in using this library rather than using -direct C low-level access: the compiler is able to **fully** optimize -the library calls -since all the functions are declared as inline. +M\*LIB is still quite-efficient: +there is no overhead in using this library rather than using +direct C low-level access as the compiler is able to **fully** optimize +the library usage +and the library is carefully designed. In [fact](https://github.com/P-p-H-d/mlib/wiki/performance), M\*LIB -is one of the fastest generic C library you can find. +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. @@ -71,6 +78,7 @@ it is highly recommended to properly define NDEBUG for released programs. 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 +as the code is quite complex and uses a lot of tricks but rather read the examples. In this documentation, 'shall' will be used to indicate a user constraint that is @@ -78,14 +86,6 @@ mandatory to follow under penalty of undefined behavior. 'should' will be used to indicate a recommendation to the user. All pointers expect non-null argument except if indicated. -A 'type' given to any macro can be either -an integer, a float, a boolean, an enum, a named structure, a pointer to such types, -or a typedef alias of any C type. -However, the preprocessing concatenation between 'type' and 'variable' into -'type variable' shall be a valid C expression. -Therefore the 'type' cannot be a C array or a function pointer -(you need to use a typedef as an intermediary named type). - Components ---------- @@ -145,6 +145,14 @@ Each header can be used separately from others: dependency between headers have ![Dependence between headers](https://raw.githubusercontent.com/P-p-H-d/mlib/master/doc/depend.png) +A 'type' given to any macro can be either +an integer, a float, a boolean, an enum, a named structure, a pointer to such types, +or a typedef alias of any C type: +in fact, the preprocessing concatenation between 'type' and 'variable' into +'type variable' shall be a valid C expression. +Therefore the 'type' cannot be a C array or a function pointer +and you need to use a typedef as an intermediary named type for such types. + Build & Installation --------------------