Author SHA1 Message Date
Patrick Pelissier 4a96845fac Improve error messages by the compiler
if the number of arguments doesn't match what is expected.
2023-11-01 11:14:27 +01:00
Patrick Pelissier b742881ebc WIP interface 2023-11-01 11:14:27 +01:00
Patrick Pelissier f7f5db61d3 Fix formatting 2023-11-01 11:13:54 +01:00
Patrick Pelissier 32b00eb433 Add new operator GENTYPE 2023-10-21 19:05:08 +02:00
Patrick Pelissier 796f2619e5 Change M_BY_NARGS semantics:
simplify suffix by __ # NARGS
instead of __NARGS_ # NARGS

Driver: reduce macro name length.
2023-10-20 00:02:38 +02:00
Patrick Pelissier 268192138a WIP M_ON_EXCEPTION 2023-10-19 22:54:51 +02:00
Patrick Pelissier 0671a2ea41 Update doc 2023-10-15 22:21:12 +02:00
Patrick Pelissier 07dce84e51 Tuple init: handle case of exception
during construction of tuple
2023-10-14 20:15:14 +02:00
Patrick Pelissier 5f4303624f Adding macro M_CHAIN_OBJ 2023-10-14 15:55:59 +02:00
Patrick Pelissier 19e61467d5 Adding tuple generation
for analysis of generated code.
2023-10-14 15:31:37 +02:00
Patrick Pelissier 1454bcebe4 Add unique name identifier
in order to avoid Wshadow warning
in generated code.
2023-10-14 15:30:57 +02:00
Patrick Pelissier d48f2ff84d Update comment 2023-10-06 22:38:36 +02:00
Patrick Pelissier 269636b4d8 Update doc with new macro M_CHAIN_INIT 2023-09-09 18:40:59 +02:00
Patrick Pelissier bf68340106 Add macro M_CHAIN_INIT for support of partially constructed object. 2023-09-09 18:40:32 +02:00
Patrick Pelissier 5dba526e29 Update ISSUES 2023-09-08 22:12:16 +02:00
Patrick Pelissier 469239adcd Update comments 2023-08-24 23:32:47 +02:00
Patrick Pelissier 589abda0c2 Fix bug in list insertion:
The output iterator has its previous field incorrect.
2023-08-13 23:27:12 +02:00
Patrick Pelissier 8f141896ba Clarify operators for memory allocation 2023-08-02 23:20:02 +02:00
Patrick Pelissier a0cbec4329 Support of output failure for serialization of strings 2023-08-02 23:20:02 +02:00
Patrick Pelissier df66db562d Add comments 2023-08-01 00:33:43 +02:00
Patrick Pelissier 1829a70601 Update documentation 2023-07-20 23:42:15 +02:00
Patrick Pelissier e9b25f2414 Rename internal field size to capacity
to match what it is used for.
2023-07-13 21:48:33 +02:00
Patrick Pelissier c9bb739f24 Fix format 2023-07-10 00:59:18 +02:00
Patrick Pelissier e049b83a9e Rename M_SUFFIX_FUNCTION_BY_NARGS in M_BY_NARGS
and updates suffix with __NARGS_
in order to be more explicit.
2023-07-10 00:58:31 +02:00
Patrick Pelissier 31ac3999a1 Add new operators 2023-07-07 22:17:39 +02:00
Patrick Pelissier a0818419ab Fix format 2023-07-04 01:08:40 +02:00
Patrick Pelissier 496f885a84 Add threads backend for FreeRTOS tasks. 2023-07-04 01:07:59 +02:00
Patrick Pelissier d5d9a4bd5c Update documentation of threads 2023-07-04 00:46:32 +02:00
Patrick Pelissier ca9571a110 Fix no stdio:
M_CSTR macro cannot be available if there is no stdio
2023-06-29 21:26:22 +02:00
Patrick Pelissier 4497214b9c Fix spelling 2023-06-29 00:32:23 +02:00
PpHd ccb1658afd Provide way of avoiding code duplication for multiple source C files
Use of compiler extension for that, only compatible for GCC /CLANG.
This provides easy and total customization (for example non template functions like strings can also avoid code duplication).
2023-06-13 23:46:58 +02:00
Patrick Pelissier eaf2783f1a Synchro with master branch 2023-06-11 23:32:42 +02:00
Patrick Pelissier 5705819814 Update doc 2023-06-11 23:32:02 +02:00
Patrick Pelissier 91f5f513c4 Update macro names
Make global logic easier.
2023-06-11 23:32:02 +02:00
Patrick Pelissier 3dec4e2cbe Fix example 2023-06-11 23:32:02 +02:00
Patrick Pelissier e70766beaa Update list of ignored file 2023-06-11 23:32:02 +02:00
Patrick Pelissier d7639f0ae0 Update example to match new semantic 2023-06-11 23:32:02 +02:00
Patrick Pelissier c63ce84e45 Update logic to select which linkage to use
so that user code can be written easily
M_USE_EXTERN_DECL / M_USE_DECL activates functions that are not inlined.
If M_USE_EXTERN_DEF / M_USE_DEF is also defined, then the definition is emitted instead of the declaration.
2023-06-11 23:32:02 +02:00
Patrick Pelissier a043c379c0 Update user code as per new liberty 2023-06-11 23:32:02 +02:00
Patrick Pelissier 92bb380117 Rewrite order in preprocessing if to simplify user code 2023-06-11 23:32:02 +02:00
Patrick Pelissier 6bb7a184db Fix compil rules 2023-06-11 23:32:02 +02:00
Patrick Pelissier fa9163be9d Make linker options optional 2023-06-11 23:32:02 +02:00
Patrick Pelissier 0bade1563c Also build exn.exe by default 2023-06-11 23:32:02 +02:00
Patrick Pelissier 1278d2f8a0 Implement noinline another way 2023-06-11 23:32:02 +02:00
Patrick Pelissier 53af2aae68 Add example of separating inline & function code 2023-06-11 23:32:02 +02:00
Patrick Pelissier 17ded6fcc8 Update M_USE_EXTERN_FINE_GRAINED to avoid warnings 2023-06-11 23:32:02 +02:00
Patrick Pelissier 19ce371533 Add support for M_USE_EXTERN_FINE_GRAINED to enable / disable inline semantics alongside the translation unit by redefining it when needed 2023-06-11 23:32:02 +02:00
Patrick Pelissier 0bd1bcb68e Another way to request the desired semantics, compatible with clang 2023-06-11 23:32:02 +02:00
Patrick Pelissier b50813713a Define internal M_INLINE:
it is used to control the inline semantics.
By combining it with optimize option "-fno-inline"
for the internal M*LIB function (using _Pragma optimize)
we can control easily if we want to use an inline version
or call of an external function.

Define new user API:
* M_USE_EXTERN_DECL : define it before including any MLIB header to requests to call the M*LIB functions and don't inline then.
* M_USE_EXTERN_DEF  : define it once in a translation unit to define the M*LIB functions. This translation unit shall contain all templated macro too.
If you use one option, you need to use the other one too for another translation unit.
2023-06-11 23:32:02 +02:00
Patrick Pelissier 2628536d20 Add +m_string_it_set_ref 2023-06-10 01:50:14 +02:00
Patrick Pelissier ecfa4a9152 Add new function string_pop_u
to pop the last unicode code point
of a string.
2023-06-03 00:59:34 +02:00
Patrick Pelissier dafe4bcec5 Add basic test for M_DEFAULT_ARGS
Print hint to developper in case of incorrect usage
2023-06-03 00:56:13 +02:00
Patrick Pelissier 8544a7f289 Update example 2023-05-30 14:01:30 +02:00
Patrick Pelissier aa18915d61 Fix overflow computation 2023-05-21 00:15:58 +02:00
Patrick Pelissier df4bc0a56c Remove alloc warning for analyzer:
it is not able to track allocations correctly and only give false warnings.
valgraind or memory sanitizer are much more reliable to track memory errors.
2023-05-13 00:52:06 +02:00
Patrick Pelissier b6046e5e23 Fix new warnings with GCC13 2023-05-13 00:52:06 +02:00
Patrick Pelissier b487bfe5ad Adding missing inline 2023-05-08 23:54:16 +02:00
PpHd 408272c810 Merge pull request
Add m_string_cat_vprintf
2023-05-08 23:35:54 +02:00
kitterion 6a9ee17eca Add tests 2023-05-08 23:17:19 +03:00
kitterion 05c5a94634 Add m_string_cat_vprintf 2023-05-08 20:52:47 +03:00
Patrick Pelissier b1b0927e9f Update examples 2023-05-06 21:54:08 +02:00
Patrick Pelissier 37770365a1 Fix several bugs:
* in case of some invalid format starting with ']' directly it wrongly assume that the parsing was valid.
* incase of exception handling, and an exception was raised during the internal parsing, some destructors wern't called.
2023-05-05 22:16:39 +02:00
Patrick Pelissier 82bdcc685a Add internal macro MQLET for internal M_LET use 2023-05-05 22:15:13 +02:00
Patrick Pelissier 26fa733f70 Fix format 2023-05-05 22:14:41 +02:00
Patrick Pelissier cd2fc05573 Add FIXED_SIZE property 2023-05-05 21:41:05 +02:00
Patrick Pelissier 33430d4359 Update 2023-04-29 18:46:09 +02:00
Patrick Pelissier dc95b49f05 Update 2023-04-29 12:07:10 +02:00
Patrick Pelissier 3ec24cfa40 Update 2023-04-29 11:41:08 +02:00
Patrick Pelissier 12b099dcf8 Update 2023-04-29 11:25:56 +02:00
Patrick Pelissier b885d6136c Update 2023-04-29 11:20:00 +02:00
Patrick Pelissier b51c4bea2b Update 2023-04-29 11:19:54 +02:00
Patrick Pelissier 302c5eb300 Remove export passthrough of NEW/DEL/REALLOC/FREE interface
from the container oplist.
It has no real practical purpose.
NEW/DEL/REALLOC/FREE shall be a property of the container
to be defined, and not a property for an already defined container.
2023-04-29 10:50:04 +02:00
Patrick Pelissier 6d2900a2bd Improve coverage of test suite. 2023-04-27 00:04:44 +02:00
Patrick Pelissier 573e09c56e Remove variable number of elements support which was not working.
Request an explicit number of elements.
2023-04-27 00:04:03 +02:00
Patrick Pelissier 0a39a17d36 The undefined number of element value of serial _array_start
is now (size_t)-1 and no longer 0.
Moreoever, a serialization interface may refuse outputting data
if it doesn't know the number of elements.
In which case, the container shall explictly compute the number
of elements and recall the serial object _array_start method.
2023-04-27 00:01:50 +02:00
Patrick Pelissier a913d0947c Rewrite code to fix coverage 2023-04-26 23:34:13 +02:00
Patrick Pelissier abbd8ad6ce Update 2023-04-26 22:56:23 +02:00
Patrick Pelissier a09c9fe1c3 Update 2023-04-26 22:56:23 +02:00
Patrick Pelissier 219c62ff5d Provide a way to alter the standard naming convention for the functions
Close #72
2023-04-22 09:33:08 +02:00
Patrick Pelissier 272a326375 Fix warning issue for coverage 2023-04-22 09:23:18 +02:00
Patrick Pelissier eca79f2c80 Improve coverage of test suite 2023-04-21 22:44:34 +02:00
Patrick Pelissier 2feda4059f Fix issue in case of invalid IO 2023-04-21 22:44:23 +02:00
Patrick Pelissier de0ef67cf2 Fix build issue with VC++ 2023-04-19 23:06:23 +02:00
Patrick Pelissier 95762a058c Fix const attribute of _get_emplace 2023-04-19 22:42:21 +02:00
Patrick Pelissier acd8671017 Fix test case according to contract. 2023-04-19 22:37:54 +02:00
Patrick Pelissier a6c1688f23 Fix issue in remove root node for tree (part 2) 2023-04-19 22:37:40 +02:00
Patrick Pelissier f6ed549ce5 Fix issue in tree_remove for root node index (Part 2)
Enable support of removing root node
In this case, it considers the first child of the root as the new root (breaking symetry)
2023-04-18 23:24:48 +02:00
Patrick Pelissier 8639fdbd98 Fix issue in tree_remove when it is root node (part 1) 2023-04-18 22:56:56 +02:00
Patrick Pelissier 693b09387f Improve coverage of test suite. 2023-04-18 22:19:41 +02:00
Patrick Pelissier 4052d3794b Tree: Transform runtime tests into assertion
as it is proven that it cannot happen.
2023-04-18 22:19:28 +02:00
Patrick Pelissier 044e9c3bf7 Fix benchmark 2023-04-17 16:56:57 +02:00
Patrick Pelissier 45a2a1afb2 Add bench for CC 2023-04-16 21:16:04 +02:00
Patrick Pelissier b44e4e09dd Don't use builtin for clang as they are not properly supported. 2023-04-16 20:11:56 +02:00
Patrick Pelissier 5158059ec4 Make m_throw a classic "cold" function rather than a static inline function.
Since the function shall be rarely called, there is no point in inlining/duplicating it
in several units.
2023-04-16 19:26:15 +02:00
Patrick Pelissier 7279011f0a Use of the builtin versions of setjmp /longjmp for GCC / CLANG
They are more than twice faster on extreme bench of M\_LET / M\_TRY scenario
(and still twice slower than C++).
They also use less stack usage.
2023-04-16 19:18:04 +02:00
Patrick Pelissier 79369e9b05 Update README 2023-04-16 19:16:08 +02:00
Patrick Pelissier 58a7a7c214 Add gene TRY 2023-04-16 19:15:54 +02:00
Patrick Pelissier e3e94ca238 Add M_ATTR_COLD_FUNCTION attribute 2023-04-16 19:15:22 +02:00
Patrick Pelissier ae81271b2a Fix name of internal variable for M_DEFER 2023-04-16 08:33:45 +02:00
Patrick Pelissier d9c3724cff Compatiblity with C++ 2023-04-15 23:18:45 +02:00
Patrick Pelissier 1ff9848384 Update test so that it tests also the case of throwing without any try section (override M_RAISE_FATAL) 2023-04-15 22:51:57 +02:00
Patrick Pelissier 83e7f2a641 Use of new M_ATTR_NO_RETURN attribute 2023-04-15 22:50:47 +02:00
Patrick Pelissier 6580601969 Add M_ATTR_NO_RETURN attribute support (not C23 compatible yet) 2023-04-15 22:50:27 +02:00
Patrick Pelissier ad023bb09d Improve coverage of the test suite 2023-04-13 23:27:01 +02:00
Patrick Pelissier b5df21f9c5 Simplify function: for LCA both iterators shall be in the same tree 2023-04-13 23:26:12 +02:00
Patrick Pelissier d2dccbf514 Add table of contents 2023-04-12 20:35:22 +02:00
Patrick Pelissier a8075cbb05 Transform runtime test into assertion
as it is proven that it cannot happen.
2023-04-11 21:57:56 +02:00
Patrick Pelissier 1322afc4c9 Improve coverage of test suite 2023-04-11 21:53:14 +02:00
Patrick Pelissier 0f885fb158 Fix coverage source for m-core 2023-04-11 21:32:57 +02:00
Patrick Pelissier 25a2eb0875 Correct syntax 2023-04-11 21:32:38 +02:00
Patrick Pelissier 6bcd51f10f Complete coverage synthesis
with branch coverage information
2023-04-11 21:09:40 +02:00
Patrick Pelissier 9c1cb9c835 Update doc 2023-04-11 00:07:33 +02:00
Patrick Pelissier 19cb329ae6 Simplfy example 2023-04-11 00:05:41 +02:00
Patrick Pelissier 8099e6a94f Update doc 2023-04-11 00:04:46 +02:00
Patrick Pelissier ce6cc080d6 Improve coverage of test suite 2023-04-10 23:09:18 +02:00
Patrick Pelissier a27b0b4014 Fix wrong parsing of malformed dict. 2023-04-10 23:08:51 +02:00
Patrick Pelissier e74f80cc59 Update doc 2023-04-08 11:32:15 +02:00
Patrick Pelissier bafd307247 Update performance chapter 2023-04-08 11:27:37 +02:00
Patrick Pelissier 6bed3ac697 Print time with 2 digits after the decimal 2023-04-08 11:25:59 +02:00
Patrick Pelissier b8a9073fc9 Fix issue to generate graph without any repetition 2023-04-08 11:25:05 +02:00
Patrick Pelissier da3e71c676 Fix introduced warning in release mode 2023-04-08 11:23:32 +02:00
Patrick Pelissier 4ea83e129e Improve coverage of test suite 2023-04-08 00:17:33 +02:00
Patrick Pelissier fc34fa80b5 Properly mark condition for entering memory failure. 2023-04-07 23:50:03 +02:00
Patrick Pelissier 4f608ec266 Fix target of run 2023-04-06 22:02:49 +02:00
Patrick Pelissier ccaa54d2a5 Improve coverage of the tet suite 2023-04-06 21:55:21 +02:00
Patrick Pelissier 095bf7070d Rewrite loop to avoid final assert(0) 2023-04-06 21:55:06 +02:00
Patrick Pelissier 676b12d5d2 Fix warnings 2023-04-05 23:15:39 +02:00
Patrick Pelissier f858aa2cb5 Improve coverage of the test suite. 2023-04-05 23:07:52 +02:00
Patrick Pelissier 9d77448a25 Reduce optimization level to 0
Otherwise the coverage results are not reliable:
* some uncovered lines are not reported as uncovered
* some covered lines are reported as uncovered (!)
2023-04-05 23:04:22 +02:00
Patrick Pelissier 8babc33b91 Rewrite code differently to be more robust
and improve coverage of the test suite
2023-04-05 22:41:33 +02:00
Patrick Pelissier 352d7cf725 Improve coverage of the test suite 2023-04-05 22:22:49 +02:00
Patrick Pelissier a6993ab758 Overload assert in coverage mode
to avoid polluting the report with untaken branch by the assert macro.
2023-04-05 22:22:01 +02:00
Patrick Pelissier 48260ac2a6 Ignore temporary coverage files 2023-04-05 22:21:23 +02:00
Patrick Pelissier e4afb024b9 Improve coverage of test suite 2023-04-05 00:38:44 +02:00
Patrick Pelissier 63008af30f Add assertions 2023-04-05 00:38:32 +02:00
Patrick Pelissier 1828aca65e Fix preprocessing 2023-04-05 00:38:16 +02:00
Patrick Pelissier 9354e9717d Remove unused test function 2023-04-04 01:06:32 +02:00
Patrick Pelissier 100c0f22fe Improve test coverage 2023-04-04 00:48:03 +02:00
Patrick Pelissier ff778528f8 Improve coverage of the test suite 2023-04-04 00:22:49 +02:00
Patrick Pelissier 8f1a1df617 Improve coverage of test suite 2023-04-03 16:38:54 +02:00
Patrick Pelissier 28faf815d7 Improve robustness against broken I/O file 2023-04-03 14:09:34 +02:00
Patrick Pelissier fe3b703d0a Don't expand isspace for coverage tests 2023-04-03 14:09:07 +02:00
Patrick Pelissier 0aa6a9f0cf Update comments 2023-04-03 13:19:50 +02:00
Patrick Pelissier 67832ac918 Add more tests case for IO parsing 2023-04-03 13:18:28 +02:00
Patrick Pelissier 669a3297c7 Fix issue in ispace usage and allow more space in formating (to be more uniform. The allowed spaces before were in strange place only) 2023-04-03 13:18:10 +02:00
Patrick Pelissier 25d4829d7b Add utilities function for parsing FILE or char* while skipping space character 2023-04-03 13:17:25 +02:00
Patrick Pelissier ebab05a789 Improve coverage of test suite 2023-04-03 12:36:35 +02:00
Patrick Pelissier 727df5b7bf Fix coverage 2023-04-03 00:36:18 +02:00
Patrick Pelissier aebe1308fc Improve coverage computation 2023-04-03 00:23:05 +02:00
Patrick Pelissier 1d163a396e Replace assert by M_ASSERT 2023-04-03 00:12:00 +02:00
Patrick Pelissier 7534aa0d61 Add internal M_UNLIKELY_NOMEM to help coverage computation 2023-04-03 00:05:29 +02:00
Patrick Pelissier 6976d4e23d Remove (broken) auto check of coverage 2023-04-02 23:02:48 +02:00
Patrick Pelissier 6b7954e141 Fix coverage for new files 2023-04-02 22:52:40 +02:00
Patrick Pelissier c27d76a83b Remove assert & contract from coverage to avoid polluting reports 2023-04-02 22:45:56 +02:00
Patrick Pelissier 0e3081bfc6 Include branch probabilities in report 2023-04-02 22:45:35 +02:00
Patrick Pelissier d754e9a15f Update doc for _get_emplace functions for associative array 2023-03-29 22:59:54 +02:00
Patrick Pelissier 4e4e21793c Add _get_emplace functions for associative array 2023-03-29 22:59:43 +02:00
Patrick Pelissier c515da9f37 Update documentation 2023-03-29 22:50:51 +02:00
Patrick Pelissier 961b93bd4c Add test for M_LET + associative array 2023-03-28 23:43:49 +02:00
Patrick Pelissier 39a719c3f0 Fix warnings 2023-03-28 23:43:21 +02:00
Patrick Pelissier 8b643b4878 Add support for emplace detection in associative array + M_LET 2023-03-28 23:43:08 +02:00
Patrick Pelissier 876c394fba Fix format 2023-03-28 23:42:25 +02:00
Patrick Pelissier 81439c9437 Fix grammar 2023-03-27 01:05:53 +02:00
Patrick Pelissier 191ef7d09e Fix grammar 2023-03-27 00:55:08 +02:00
Patrick Pelissier bd4131dd8f Fix typo 2023-03-27 00:53:31 +02:00
Patrick Pelissier cfe8293c64 Cleanup documentation 2023-03-25 10:25:52 +01:00
Patrick Pelissier ea2715aa75 Remove static assert. Some old compilers failed to simplify into a constant expression, resulting in build failure 2023-03-24 23:54:49 +01:00
Patrick Pelissier f69cec6820 Fix warning with clang+const char * type 2023-03-24 21:53:23 +01:00
Patrick Pelissier 085f371693 Update doc 2023-03-24 21:12:28 +01:00
Patrick Pelissier 16a0a5c1a3 Add new examples 2023-03-24 21:11:15 +01:00
Patrick Pelissier 3953f81884 Update 2023-03-24 21:10:59 +01:00
Patrick Pelissier 8365888e6e Add Oplist inheritanc chapter 2023-03-24 20:38:51 +01:00
Patrick Pelissier c3f6e3c5f0 Add trivial script to separate preproc of compilation for debug 2023-03-19 00:29:51 +01:00
Patrick Pelissier 4cafe4dce1 Fix steps to debug 2023-03-19 00:29:06 +01:00
Patrick Pelissier 9f8b97ae46 Rename fields of m_exception_t:
data->context
n->num
2023-03-18 18:11:23 +01:00
Patrick Pelissier 030bea9c11 Add test for M_DEFER & M_LET_IF in exceptions 2023-03-18 17:57:46 +01:00
Patrick Pelissier e33894f1b3 Finish support for M_DEFER / M_LET_IF & exceptions 2023-03-18 17:57:15 +01:00
Patrick Pelissier 66f5e6c67d Support for more than one expression in M_DEFER 2023-03-18 17:56:44 +01:00
Patrick Pelissier 78c6dce068 Update doc 2023-03-18 17:56:11 +01:00
Patrick Pelissier 0798480ad5 Refactoring & implement support for RAII with M_DEFER 2023-03-18 17:39:56 +01:00
Patrick Pelissier e8322215fd Update doc about clang 2023-03-18 17:39:20 +01:00
Patrick Pelissier 42d3042c15 Add NOCLEAR property to M_BASIC_OPLIST and prepare injection for M_DEFER 2023-03-18 17:25:08 +01:00
Patrick Pelissier b7214ad11d Adding test of NOCLEAR property 2023-03-18 17:20:30 +01:00
Patrick Pelissier 08b4bc9052 M_LET_IF reuses clear mechanism provided by M_DEFER 2023-03-18 15:14:31 +01:00
Patrick Pelissier d813171e8a Add new test generation 2023-03-18 09:15:39 +01:00
Patrick Pelissier d1094999f5 Update M_ASSERT to separate requirement for predicate 2023-03-18 09:15:11 +01:00
Patrick Pelissier c8354aa6ed Update doc 2023-03-18 08:08:33 +01:00
Patrick Pelissier ab3aa33fac Add M_SET_THROUGH_INIT_SET 2023-03-18 08:08:23 +01:00
Patrick Pelissier 01f2f376e2 Update doc 2023-03-18 00:21:46 +01:00
Patrick Pelissier 535e00366a Correct reported errors 2023-03-18 00:21:37 +01:00
Patrick Pelissier 42111ec22a Rename field of m_exception_t 2023-03-17 22:13:18 +01:00
Patrick Pelissier ef0e849616 Fix test 2023-03-17 22:04:50 +01:00
Patrick Pelissier 9c516c2055 Update doc 2023-03-17 21:56:27 +01:00
Patrick Pelissier db48b985c3 Update doc 2023-03-17 21:48:56 +01:00
Patrick Pelissier 888796ca06 Update doc 2023-03-17 21:48:07 +01:00
Patrick Pelissier 144ae9c5ed Add ID support for GAIA 2023-03-17 21:47:04 +01:00
Patrick Pelissier 6223c93b53 Update doc 2023-03-17 20:21:19 +01:00
Patrick Pelissier 30f7656822 Update documentation 2023-03-17 20:15:42 +01:00
PpHd 8209a0c32a Merge pull request #107 from jonadem/patch-1
Fix typos
2023-03-17 20:14:38 +01:00
Jona 92e6957320 Fix typos 2023-03-17 14:00:49 +01:00
Patrick Pelissier b3c9f6ee47 Add support of exception for Visual C++ 2023-03-14 20:00:11 +01:00
Patrick Pelissier ab8bbad3f4 Fix syntax 2023-03-13 23:54:52 +01:00
Patrick Pelissier 9047376b7f Add m-try.h in HEADER 2023-03-13 23:53:36 +01:00
Patrick Pelissier dfed8dbc50 Fix format 2023-03-13 23:53:26 +01:00
Patrick Pelissier 2d3c25cd85 TCC doesn't support the __thread attribute,
which is a GCC extension.
Use this extension only for GCC.
2023-03-13 23:45:28 +01:00
Patrick Pelissier bfa948dc7a Add WIP implementation for the exception memory model:
add header m-try that defines the M_TRY / M_CATCH macros
that macros similarly to the C++ try / catch keywords.
Add implementation for C++, GCC, CLANG and pure C compiler.
2023-03-13 23:31:50 +01:00
Patrick Pelissier 94b6d1b9fd Fix computation of HASH_FINAL 2023-03-13 22:17:10 +01:00
Patrick Pelissier 0ddd5ddc6d Add AARCH64 target for CI 2023-03-13 21:04:05 +01:00
Patrick Pelissier cba93d5bb4 Add SC library 2023-03-12 21:12:21 +01:00
Patrick Pelissier d02de75487 Add control that all initialized testobj are properly cleared at the end of the test suite 2023-03-12 20:29:58 +01:00
Patrick Pelissier 2f57766249 Rename NOEXCEPT to NOCLEAR property as NOEXCEPT
doesn't provide enough guarantee to the exception handler.
2023-03-12 20:23:31 +01:00
Patrick Pelissier 3ff01e37eb Update documentation for properties 2023-03-05 19:44:36 +01:00
Patrick Pelissier 5683df0f22 Adding test for M_TEST_NOEXCEPT_P 2023-03-05 19:44:21 +01:00
Patrick Pelissier 11dc7afc06 Add NOEXCEPT property and M_TEST_NOEXCEPT_P macro to test it 2023-03-05 19:44:04 +01:00
Patrick Pelissier 9e2ae3f101 Update example 2023-03-05 18:30:47 +01:00
Patrick Pelissier c35aa9c891 Replace the M_ASSERT(0) by M_ASSUME(0) since they are not reachable (in order to inform the compiler of this fact) 2023-03-05 00:50:40 +01:00
Patrick Pelissier 2fc31d8c12 Factorization find of item in prioqueue 2023-03-03 23:23:06 +01:00
Patrick Pelissier 4f8d0a7156 Split macro 2023-03-03 23:12:40 +01:00
Patrick Pelissier aaf5bbd6a0 Separate IO from core macro 2023-03-03 23:03:24 +01:00
Patrick Pelissier 2f76652f2b Maintenance 2023-03-03 22:50:14 +01:00
Patrick Pelissier 942cf32519 Maintenance: separate macros for type and core functions. 2023-03-03 22:02:07 +01:00
Patrick Pelissier c1c9cb9cd3 Update example 2023-03-03 20:12:50 +01:00
Patrick Pelissier 76bfb48685 Update freebsd CI to be more robust. 2023-03-02 23:41:59 +01:00
Patrick Pelissier afff412f7a Maintenance: continue splitting huge macros into smaller ones. 2023-03-02 00:39:08 +01:00
Patrick Pelissier e48dcdeecc Factorization & assertions 2023-02-27 14:05:59 +01:00
Patrick Pelissier 12fae5c36c Update example 2023-02-26 23:43:57 +01:00
Patrick Pelissier 3f9129c7ed Update comments 2023-02-26 23:43:57 +01:00
Patrick Pelissier b918f61f4f Update example 2023-02-26 23:43:57 +01:00
Patrick Pelissier 93b69d0f8b Fix call of memcpy with size=0 and src=NULL 2023-02-25 12:17:18 +01:00
Patrick Pelissier b3440a2edd Fix position of assertions 2023-02-24 20:35:32 +01:00
Patrick Pelissier 4140df5bfc Improve test suite 2023-02-24 19:56:56 +01:00
Patrick Pelissier fbab093d52 Avoid warnings about variables never read. 2023-02-24 19:56:26 +01:00
Patrick Pelissier f57a0e0bf8 Update README 2023-02-24 18:21:39 +01:00
Patrick Pelissier 925c06beb8 Fix usage of va_copy 2023-02-24 15:07:29 +01:00
Patrick Pelissier 8e2f67b794 Fix building on exe files: some targets don't link with LDFLAGS if it is not in the last argument 2023-02-23 12:42:11 +01:00
Patrick Pelissier f176d01e49 Fix README 2023-02-23 10:53:32 +01:00
Patrick Pelissier 2b99bbe956 Remove bool oplist as it is globally registered 2023-02-22 22:47:31 +01:00
Patrick Pelissier 700bfc5341 Add documentation for RET in API transformation 2023-02-22 22:47:17 +01:00
Patrick Pelissier 4062525821 Add test for RET in API transformation 2023-02-22 22:47:06 +01:00
Patrick Pelissier 800a1e5c36 Add support for RET in API transformation and register global bool oplist 2023-02-22 22:46:46 +01:00
Patrick Pelissier 1838f675a7 Add more comments, another alternative.
Rename some variables to be clearer.
2023-02-18 20:15:17 +01:00
Patrick Pelissier bf6c1341b3 Add comments to explain what we do
Always use the prefixed version of M*LIB
2023-02-18 09:58:30 +01:00
Patrick Pelissier 55b745b916 Use of M_WORKER_SPAWN_DEF2 in example:
it shows how to add paralelization to a code base.
2023-02-18 00:25:30 +01:00
Patrick Pelissier 5cb0d9214b Adding doc for M_WORKER_SPAWN_DEF2. 2023-02-18 00:25:17 +01:00
Patrick Pelissier 8f99b8e617 Adding test for M_WORKER_SPAWN_DEF2 2023-02-18 00:25:06 +01:00
Patrick Pelissier d2ce71a90a Adding M_WORKER_SPAWN_DEF2 for providing specialization
and type-safe variant of m_worker_spawn.
2023-02-18 00:24:20 +01:00
Patrick Pelissier 8562986eea Avoid dereferencing the table in asserts if the lock is done on the tree:
it usually means that the tree is partially accessed by other
threads (at least the derefencing methods which should be
safe).
2023-02-18 00:15:31 +01:00
Patrick Pelissier ee89858bf0 Add renaming of header in compatibility chapter 2023-02-16 00:20:07 +01:00
Patrick Pelissier 085d7157c0 Add compatibility layer with old header m-mutex
as a transition for current programs.
2023-02-16 00:10:55 +01:00
Patrick Pelissier 91f3174a36 Rename m-mutex header into m-thread
as it is not just about mutex but about thread functions
just like the header pthread or thread.h
2023-02-16 00:09:06 +01:00
Patrick Pelissier 56f51c59af Add comments about locale dependent functions. 2023-02-11 23:47:11 +01:00
Patrick Pelissier df0c95ca46 Adding note on locale for JSON outputs 2023-02-11 14:35:36 +01:00
Patrick Pelissier 482ec38e62 Fix wrong use of isprint function. 2023-02-11 14:34:13 +01:00
Patrick Pelissier 82743ca72c Update pipeline for freebsd 2023-02-11 09:28:12 +01:00
Patrick Pelissier 312821454c Avoid running tests in example for freebsd 2023-02-11 00:39:06 +01:00
Patrick Pelissier c953e87660 Link with stdthreads for FreeBSD 2023-02-11 00:11:48 +01:00
Patrick Pelissier 8846707c8b Fix issue on FreeBSD when building in C11 mode:
thrd_sucess is not equal to 0 on this system,
so replace 0 by thrd_success
2023-02-11 00:08:51 +01:00
Patrick Pelissier bf7d4eee55 Avoid using .log suffix for failure checks
some Make program (like FreeBSD one) doesn't handle
priority of a specific rule over a generic rule.
So the generic rule is used for failure checks and it fails the check.
Use another suffix to avoid collision between rules
2023-02-10 23:57:28 +01:00
Patrick Pelissier d4dc85f89a Add FreeBSD target for CI 2023-02-10 21:36:04 +01:00
Patrick Pelissier 130c32e7d4 Include only sysinfoapi.h on Windows machine to reduce dependency
Add fallback to _SC_NPROCESSORS_CONF if _SC_NPROCESSORS_ONLN is not supported (Android)
2023-02-07 23:17:03 +01:00
Patrick Pelissier 2bcaba3bc0 Factorize into smaller macros 2023-02-06 22:17:12 +01:00
Patrick Pelissier 443c805c22 Fix format 2023-02-06 21:28:19 +01:00
Patrick Pelissier 414c87bb69 Rename internal macros 2023-02-05 23:38:29 +01:00
Patrick Pelissier e9ca506d93 Factorization of macros 2023-02-03 20:53:27 +01:00
Patrick Pelissier 8e58f7d637 Factorize into smaller generation macros. Add emplace support for MPMC/SPSC queues 2023-02-01 20:58:28 +01:00
Patrick Pelissier 254beaf3c7 Factorize into smaller generation macros 2023-02-01 20:43:01 +01:00
Patrick Pelissier 27735eb224 Migrate version of action scripts. 2023-01-29 00:19:22 +01:00
Patrick Pelissier 0afc81bd54 Simplify example by using emplace function. 2023-01-28 14:49:17 +01:00
Patrick Pelissier 39e67eebdc EMPLACE: Fix expansion of methods as macro in the oplist
by performing another evaluation step.
2023-01-28 14:49:07 +01:00
Patrick Pelissier 840226c7fd TREE: Add documentation of emplace functions 2023-01-28 14:48:58 +01:00
Patrick Pelissier e421851525 TREE: Add tests for emplace functions 2023-01-28 14:48:50 +01:00
Patrick Pelissier f70b52c9e4 TREE: Add support for emplace functions 2023-01-28 14:48:12 +01:00
Patrick Pelissier 40249ce5bc Separate macros into smaller more functionnal ones 2023-01-28 14:48:01 +01:00
Patrick Pelissier 97ff413f01 Maintenance:
Separate big macros into several smaller ones
2023-01-22 23:33:13 +01:00
Patrick Pelissier 8e4ac99a35 Separate macro into smaller macros (more maintenable) 2023-01-20 23:45:40 +01:00
Patrick Pelissier 4366e8eeab Separate macro into smaller macros
to ease reading and enable easier customization of generation
2023-01-20 23:45:40 +01:00
Patrick Pelissier 4e5e498bb2 Add new library 2023-01-09 23:35:33 +01:00
Patrick Pelissier 870a6f4b57 Update to 0.7.1 2023-01-02 13:06:29 +01:00
Patrick Pelissier a2ae209992 Happy new year 2023-01-02 12:57:41 +01:00
Patrick Pelissier 43fdd10e77 Release 0.7.0 2022-12-27 20:01:44 +01:00
Patrick Pelissier b1183de0f8 Update example to allow more example of promotion. 2022-12-25 23:12:02 +01:00
Patrick Pelissier 3a3ef7454c Fix conflict issue between INIT_WITH_VAI macro and API transformation.
Since both used M_MAP2_C macro, the final expansion was stopped if an
API generic transformation was requested in INIT_WITH_VAI.
Duplicate M_MAP2_C internally for API transformation.
2022-12-24 23:04:42 +01:00
Patrick Pelissier 5f946b728b Update example to include more integration of the different features
(enabling to test more).
2022-12-24 23:03:48 +01:00
Patrick Pelissier 9cc03ff81b Add macro M_INIT_WITH_THROUGH_EMPLACE_TYPE that provides an INIT_WITH
method that scans the different methods provided in EMPLACE_TYPE and
try to search for a matching one.
2022-12-23 11:49:08 +01:00
Patrick Pelissier 89d4db174e Fix format 2022-12-23 11:48:15 +01:00
Patrick Pelissier f5bbc0a7fb Implement multiple kind of workarounds for GCC 12
as it produces more false warnings

Include missing header in C++ mode
2022-12-22 20:42:20 +01:00
Patrick Pelissier 9da0d1d94b Add new internal macro M_TAIL_3 2022-12-22 15:49:10 +01:00
Patrick Pelissier fafaaafdbf Avoid warning for M_RET_ARG if there is the exact number of argument.
Add internal M_TRIPLE_* macros (TBC)
2022-12-22 14:05:46 +01:00
Patrick Pelissier 38f4107b19 Support of keyptr /valueptr iterator 2022-12-04 23:39:42 +01:00
Patrick Pelissier cbefdab4bb Add check of B+TREE map against C++ map 2022-12-04 21:26:20 +01:00
Patrick Pelissier bcd0c46e8b Simplify & factorize the instances of the check against C++ 2022-11-30 23:56:29 +01:00
Patrick Pelissier f25bb73e58 Add comparison to C++ unorder_map 2022-11-30 00:30:45 +01:00
Patrick Pelissier ea3584e048 Rename internal macro to internal namespace 2022-11-29 23:16:55 +01:00
Patrick Pelissier 85473610a4 Update doc 2022-11-22 22:51:40 +01:00
Patrick Pelissier f9f0b307fc Provide even shorter example using EMPLACE_TYPE 2022-11-10 13:50:00 +01:00
Patrick Pelissier d17fa4530b Update comments 2022-11-05 13:36:57 +01:00
Patrick Pelissier 3806495e2d Fix spelling 2022-11-04 10:41:38 +01:00
Patrick Pelissier 15f58d5738 Update example comments. 2022-10-23 21:01:44 +02:00
Patrick Pelissier 4de7da1c05 Adding bench for emhash
https://github.com/ktprime/emhash
2022-10-15 10:24:18 +02:00
Patrick Pelissier 93229c61f2 Update comments 2022-10-12 23:26:33 +02:00
Patrick Pelissier 3f0e8956b8 Add emplace method for buffer. 2022-10-11 22:47:14 +02:00
Patrick Pelissier b82670b643 Add emplace support for concurrent. 2022-10-10 23:08:30 +02:00
Patrick Pelissier 64800dbd3f Use of type from oplist rather than meta name
(more coherent)
2022-10-10 23:06:02 +02:00
Patrick Pelissier 2d9d9fbd9f Remove obsolete macros 2022-10-10 22:54:48 +02:00
Patrick Pelissier f0ba5d17f4 Rework fuzzer support to be fully generic. 2022-10-10 22:47:43 +02:00
Patrick Pelissier e51c988222 Add initial support for fuzzing 2022-10-07 23:39:54 +02:00
Patrick Pelissier 0be3900beb Enable support for external testsuite from stdin
instead of pseudo random values.
This will enable to connect it to a fuzzer.
2022-10-07 23:28:12 +02:00
Patrick Pelissier f60ce0320a Port to new API version of STC. 2022-10-07 22:47:53 +02:00
Patrick Pelissier 77008b8622 Fix leak of memory in non optimized _safe_get
of B+Tree.
2022-10-03 23:07:13 +02:00
Patrick Pelissier a7617002c5 Update documentation for emplace generation. 2022-10-03 22:54:42 +02:00
Patrick Pelissier bc73616bde Add test cases for emplace generation
for dict & B+tree
2022-10-03 22:40:44 +02:00
Patrick Pelissier d6b9b054c2 Fix emplace generation
(incorrect value oplist)
2022-10-03 22:34:13 +02:00
Patrick Pelissier 9eed4be97c Add emplace support for B+Tree 2022-10-03 22:16:50 +02:00
Patrick Pelissier 2519927178 Fix build in case of no MPFR and warnings are treated as errors. 2022-10-02 22:31:50 +02:00
Patrick Pelissier 0fec33b38e * Add emplace generation for dict/hashmap.
(still need more tests).
* Factorize emplace generation for R+TREE/Prioqueue
2022-10-02 22:24:22 +02:00
Patrick Pelissier dc2b6d2b2d Fix detection of GMP / MPFR. 2022-10-02 22:16:45 +02:00
Patrick Pelissier bc63edc595 Fix emplace generation for asso array 2022-10-02 21:41:21 +02:00
Patrick Pelissier 6241a3093c Factor comments. 2022-10-02 21:35:52 +02:00
Patrick Pelissier fb53a464d7 Update comments 2022-10-01 20:41:45 +02:00
Patrick Pelissier aba26b75a2 Fix chapter in documentation 2022-10-01 11:40:23 +02:00
Patrick Pelissier 775ec6f91b Make M_ASSERT_INDEX more robust
in case it is called with a signed integer.
The trick was using x-x to represent 0 so that
the compiler won't complain with the comparaison
x >= 0 when it is called with unsigned number.
2022-10-01 11:38:11 +02:00
Patrick Pelissier 95bc7063a0 Remove some warning with clang:
it complains about using a GNU extension
in GNU mode (gnu11)!
2022-10-01 11:36:14 +02:00
Patrick Pelissier 731d3ecf1a Update error chapter of the documentation 2022-10-01 09:50:38 +02:00
Patrick Pelissier 0d1817e7ca Add tiny example of no stdio support. 2022-10-01 09:50:24 +02:00
Patrick Pelissier 1a5b428bfb Fix proper support of no stdio
and add macro M_RAISE_FATAL to raise a fatal error
with the default is using stdio.
2022-10-01 09:50:09 +02:00
Patrick Pelissier bd49e31f3b Add definition macros for emplace/associative array container. 2022-09-29 23:48:46 +02:00
Patrick Pelissier 2dba83e3c5 Remove M_USE_STDLIB
(It wasn't working at all).
2022-09-28 22:16:04 +02:00
Patrick Pelissier 75e9766da9 Fix wrong generation for emplace / value 2022-09-26 23:43:39 +02:00
Patrick Pelissier d2f8aa1c0d Update documentation. 2022-09-25 22:15:44 +02:00
Patrick Pelissier 4aa4b7693f Add M_C5_EMPTY macro
Add M_CROSS_MAP2 macro
Add emplace generation  for associative array if both key & value are emplace types
Add test cases.
2022-09-25 22:13:51 +02:00
Patrick Pelissier d50b450927 Update documentation. 2022-09-25 00:36:27 +02:00
Patrick Pelissier 5674cdbfc5 Add new macro M_CROSS_MAP
enabling to map a function to each pair
of arguments given two arglists.
2022-09-25 00:30:23 +02:00
Patrick Pelissier 3641829198 M_INC (resp. M_DEC) of M_UNDERFLOW (resp. M_OVERFLOW)
will keep the initial error.
2022-09-16 18:46:13 +02:00
Patrick Pelissier 10a759b09e Add another function for generation 2022-09-15 23:25:42 +02:00
Patrick Pelissier b5a3b36c1b * Add M_C3_EMPTY function.
* Add WIP generator for emplace functions for associative array. What is missing is the hard part (even what is done cannot be said as easy!) Generation of both N x M functions. It probably needs a new MAP function for this.
2022-09-15 23:25:38 +02:00
Patrick Pelissier b0c3839f2b Add serial methods in documentation. 2022-09-15 21:39:17 +02:00
Patrick Pelissier 3aa3e95e4c Remove constraint of calling string_end_p
before string_next or string_get_cref
This generates slighty more code but it is much saner
from user point of view.
2022-09-13 00:18:15 +02:00
Patrick Pelissier 87f1e53e13 Add more basic iteration code generation analysis 2022-09-13 00:03:40 +02:00
Patrick Pelissier d7b45cc220 Fix issue in string_previous 2022-09-11 23:14:52 +02:00
Patrick Pelissier d8142a9764 Add precision on documentation. 2022-09-10 16:38:27 +02:00
Patrick Pelissier 8780f58739 Fix description of string_unocde_t 2022-09-10 16:35:38 +02:00
Patrick Pelissier e352104df8 Update documentation with new function. 2022-09-10 16:30:57 +02:00
Patrick Pelissier cbb2b452bb Add string_previous function
to iterate on the previous UTF8 code point.
2022-09-10 16:30:45 +02:00
Patrick Pelissier 6e947c6262 Add more corner cases. 2022-09-10 16:21:19 +02:00
Patrick Pelissier 18f04da4ec Robustness/fix:
string_next won't advance if the end of string is reached.
2022-09-10 16:19:58 +02:00
Patrick Pelissier 3dad6ef65c Update string API description. 2022-09-10 16:16:42 +02:00
Patrick Pelissier 41c4f5fe5c Add string functions :
* string_it_get_pos to return the position in the steam
* string_it_pos to start iterating from a given position.
2022-09-10 16:16:13 +02:00
Patrick Pelissier cfeedf19f8 Rework to be more compliant (as far as it is possible)
to real cases.
2022-09-10 15:56:36 +02:00
Patrick Pelissier 2ab410bd6a Update comments to reflect that we work
on UTF8 code points and not Unicode characters.
2022-09-10 10:39:04 +02:00
Patrick Pelissier aefbc5b2f5 Factorize the test of the start of an UTF8 code point
in a separate function
2022-09-10 10:34:54 +02:00
Patrick Pelissier abec9c37fa Clarify API
It iterates over UTF-8 code points, not Unicode characters
They can be different (!)
2022-09-10 10:32:34 +02:00
Patrick Pelissier 442b0e7cea Reduce size of struct string_it_t on 64 bits
by storing an offset to the next character
instead of a pointer. An offset can be stored as a
BYTE instead of a PTR since UT-8 can use at most
4 characters per code point.
2022-09-10 09:59:06 +02:00
Patrick Pelissier 0b853c6d52 Fix bug on bitset_resize function in case of increase of size:
the first limb may not be cleared properly in some cases.
(Reported by David M. Lary)
2022-09-04 19:27:38 +02:00
Patrick Pelissier cc7fc66899 Add bitset_ctz function 2022-08-29 19:31:19 +02:00
Patrick Pelissier 6b994c2928 Add m_core_ctz32 & m_core_ctz64 functions
(Count trailing zeros)
2022-08-29 19:30:09 +02:00
Patrick Pelissier e6fe36d3cd Revert "Perform coverage check by continuous integration tests."
as the numbers of lines generated by the generation macros
(which are included in the coverage measure)
through the C preprocessor depend on the exact version
of the C preprocessor.
There is no reliable way to get a measure on it,
except by always targeting the same compiler.
So, this measure of coverage (number of lines)
is not suitable for CIT. Ratio seems also not reliable enough.

This reverts commit f45ededf8b.
2022-08-22 23:53:10 +02:00
Patrick Pelissier f45ededf8b Perform coverage check by continuous integration tests. 2022-08-20 23:33:48 +02:00
Patrick Pelissier ed27bedcb4 Make coverage perfoms a check that the computed coverage is at least
not lower than the reference coverage, ensuring no regression
on the coverage of the tests can occur.

NOTE: some tests (m-i-shared) perform some dynamic test cases
where the exact coverage depend on the exact dynamic behavior
of the test. And this behavior is not always reproducible
(for exact the calls to m_core_backoff_wait may not occur
if the threads are not trying to grab the resource at the
exact same time).
As such, the reference of such tests is taken from the worst
case of execution of the coverage (with the lowest number
of lines covered).
2022-08-20 23:29:02 +02:00
Patrick Pelissier eb1a7a0435 Add more tests for tree 2022-08-19 23:16:42 +02:00
Patrick Pelissier de00fdc5f7 Update documentation 2022-08-13 23:50:51 +02:00
Patrick Pelissier 8febe12c5c Make stdlib an optional header 2022-08-09 00:20:32 +02:00
Patrick Pelissier 1368b201eb Fix warnings in release mode. 2022-08-09 00:19:55 +02:00
Patrick Pelissier 4ca166b0b9 Update examples to remove warnings with assertion disabled. 2022-08-09 00:19:26 +02:00
Patrick Pelissier c13533cf21 Fix naming 2022-08-08 01:22:05 +02:00
Patrick Pelissier 9fdf0f76e7 Add documentation of generic tree. 2022-08-08 01:20:30 +02:00
Patrick Pelissier 308f513edc As the allocated array offers write access to the index -1
remove if conditions to always access the array even for -1
The term tab[-1] will be filled with no pertinent value, but
we don't care about it.
2022-08-02 23:21:39 +02:00
Patrick Pelissier 900bcc3819 The internal array of the tree always allocates one more term,
so that the index -1 in the array exists and can be written.
2022-08-02 23:02:59 +02:00
Patrick Pelissier b6e0994dfc Add test case for _init_set with empty tree. 2022-08-02 23:02:33 +02:00
Patrick Pelissier 121339d948 Add _move_* functions for generic tree. 2022-08-01 22:17:26 +02:00
Patrick Pelissier c5bb84013a Create _raw methods for insertions. 2022-08-01 22:13:41 +02:00
Patrick Pelissier 65b49268d3 Fix allow_realloc for tree 2022-07-30 16:14:03 +02:00
Patrick Pelissier ecebd62f86 Update API compatibility documentation due to the _str to _cstr suffix change.
Note: the old (& still official) naming for the string functions
is still compatible since we have changed only the new namings (with m_ prefix).
See #99
2022-07-30 12:02:58 +02:00
Patrick Pelissier 6a8c9a703d Rename string functions as per latests changes 2022-07-30 12:02:32 +02:00
Patrick Pelissier ad05ae9aa5 Rename the string _suffix for Bounded Strings from _str to _cstr
See #99
2022-07-30 12:01:36 +02:00
Patrick Pelissier abffe201e5 Change the suffix of the functions dealing with C-String to _cstr
instead of _str.
See #99 for details.
2022-07-30 12:00:55 +02:00
Patrick Pelissier ee2bc27bda Fix issue in serial-bin
Note: this is a classic c error, so it may be interresting to discover
why the static analysis tools didn't report this error.
2022-07-30 04:40:09 +02:00
Patrick Pelissier 14b94865b7 Starting document tree. 2022-07-28 23:25:57 +02:00
Patrick Pelissier 6e1ceafcc2 Add more tests for tree. 2022-07-28 23:22:07 +02:00
Patrick Pelissier 58746560e9 Add comment 2022-07-28 23:21:54 +02:00
Patrick Pelissier 082adca3e6 Add test case 2022-07-27 23:48:59 +02:00
Patrick Pelissier ee1dc2a8e8 Fix issue in _graft_child 2022-07-27 23:48:40 +02:00
Patrick Pelissier 92e2d835bd Add more generic random tests 2022-07-26 23:12:41 +02:00
Patrick Pelissier 22aba04b47 Activate optimisation for coverage 2022-07-26 23:12:19 +02:00
Patrick Pelissier 399c615915 Fix issue in unlink 2022-07-26 23:04:15 +02:00
Patrick Pelissier cbdba0941a Adding more test cases 2022-07-26 22:49:07 +02:00
Patrick Pelissier 90c54a48d0 Remove uneeded test 2022-07-26 22:48:47 +02:00
Patrick Pelissier 22b18830f7 Improve test suite by performing no op swap operation randomly 2022-07-24 21:12:59 +02:00
Patrick Pelissier dab085e3a7 Fix other issue 2022-07-24 21:11:08 +02:00
Patrick Pelissier 66fac10a98 Fix corner case 2022-07-24 21:09:35 +02:00
Patrick Pelissier e5fb5ddde1 Fix some issues in insertion 2022-07-24 20:40:31 +02:00
Patrick Pelissier dcf20fbbd6 Add some tests for swap_at 2022-07-24 00:48:18 +02:00
Patrick Pelissier 5d659877fe Fix some bugs in the swap of node in a tree 2022-07-24 00:47:43 +02:00
Patrick Pelissier a30dd69aaa Add more tests for tree 2022-07-18 23:42:25 +02:00
Patrick Pelissier b1f698bb7b Fix tree _prune function 2022-07-18 23:42:13 +02:00
Patrick Pelissier 2323420a87 Add more test cases 2022-07-15 17:23:56 +02:00
Patrick Pelissier 7e120a3615 Add missing assertions 2022-07-15 16:54:51 +02:00
Patrick Pelissier 804db294ca Update test suite 2022-07-15 16:48:54 +02:00
Patrick Pelissier d12aa6c263 Don't expand tree contract for coverage 2022-07-15 00:32:26 +02:00
Patrick Pelissier d59e87d2bf Adding tests for OUT_STR/IN_STR 2022-07-07 22:21:29 +02:00
Patrick Pelissier 8f3c0af548 Add OUT_STR & IN_STR methods for tree 2022-07-07 22:21:14 +02:00
Patrick Pelissier 1f3013c445 Adding more corner cases 2022-07-07 22:10:00 +02:00
Patrick Pelissier f13e99ab1a Add coverage computation for tree 2022-07-07 22:09:51 +02:00
Patrick Pelissier fb8ad84675 Add more tests 2022-07-05 22:46:24 +02:00
Patrick Pelissier 12608afe10 Fix issue in comparing tree 2022-07-05 22:46:13 +02:00
Patrick Pelissier f97e92b4cb Complement basic tests 2022-07-04 20:47:53 +02:00
Patrick Pelissier a74e26e3de Add random generated insertion in a tree 2022-07-04 20:38:51 +02:00
Patrick Pelissier a30b783692 First basic test of tree container 2022-06-28 23:28:45 +02:00
Patrick Pelissier e64a6a22e7 Fix issues in tree 2022-06-28 23:28:09 +02:00
Patrick Pelissier 76892afa13 Fix some warnings. 2022-06-27 23:35:05 +02:00
Patrick Pelissier dcb1eb0d94 First version of IO for the tree container 2022-06-25 17:29:04 +02:00
Patrick Pelissier 950ea224ff Adding untested classic functions for tree (_init_set, _set, _equal, _hash, ...) 2022-06-18 15:26:19 +02:00
Patrick Pelissier b22a844007 update doc 2022-06-17 22:56:37 +02:00
Patrick Pelissier 502756c731 Simplify the control flow to count for utf8 encoded characters 2022-06-16 23:58:23 +02:00
Patrick Pelissier e38dc19ea1 Add current restriction on worker_spawn 2022-06-15 00:55:41 +02:00
Patrick Pelissier 2bebb2b4a1 Update example with new tree functions 2022-06-13 23:21:06 +02:00
Patrick Pelissier 5b7be93c1a Update tree:
* fix swap and add an additional argument to swap or not the child
* add sort functions for the children of a nodes
2022-06-13 23:21:06 +02:00
Patrick Pelissier d04270ae3f Proper use of API transformation for CMP operator in tuples 2022-06-13 23:21:06 +02:00
Patrick Pelissier 1bef7c1977 Fix formatting 2022-06-13 23:21:06 +02:00
Patrick Pelissier ae037ff7af Fix location of library in makefile 2022-06-13 22:12:56 +02:00
Patrick Pelissier a4267d60df Add usage of emplace with tuple 2022-06-04 23:44:22 +02:00
Patrick Pelissier 47e32ab2b3 Add support for EMPLACE_TYPE in TUPLE generations.
As a consequence, the oplist arguments for TUPLE_OPLIST
are much more rigorous. It shall really be the real oplists
of the types used to create the tuple, otherwise a compilation
error may be generated.
2022-06-04 23:41:18 +02:00
Patrick Pelissier 5ac08e42d8 Adding const for the type generation in emplace 2022-06-04 23:40:36 +02:00
Patrick Pelissier 9c59684b61 Fix the OPLIST args of TUPLE_OPLIST so that the given oplists match the types used for the definition of the tuple 2022-06-04 23:34:46 +02:00
Patrick Pelissier f26e1e5a12 Fix issue in case of recursive call of INIT_WITH with conditionnal INIT_WITH 2022-06-04 23:27:13 +02:00
Patrick Pelissier 1cde4633e6 Adding more corner cases 2022-06-04 23:26:03 +02:00
Patrick Pelissier 1393f8e9aa Update comments 2022-06-04 16:03:06 +02:00
Patrick Pelissier bfffa1d245 Update comments & naming 2022-06-04 16:02:58 +02:00
Patrick Pelissier 3a6b568ccc Update example to count the number of lines 2022-06-04 14:55:32 +02:00
Patrick Pelissier 453a920af8 Add methods to scan in post-order a sub-tree 2022-06-04 14:54:51 +02:00
Patrick Pelissier 1fd86ffc2e Update & fix 2022-06-03 22:59:55 +02:00
Patrick Pelissier 96a0639a8a Add more functions for TREE 2022-06-03 21:43:33 +02:00
Patrick Pelissier c12d0a3f23 Update comments 2022-06-03 21:43:15 +02:00
Patrick Pelissier cac8790405 Start working on example with generic tree 2022-06-01 19:52:28 +02:00
Patrick Pelissier ccd9726e01 Fix some warnings / errors 2022-06-01 19:51:50 +02:00
Patrick Pelissier 5516b50b3a Add WIP / untested generic tree datastructure 2022-05-31 23:00:19 +02:00
Patrick Pelissier b5a3e010d8 Add {} for if 2022-05-26 22:13:24 +02:00
Patrick Pelissier 2d7d267252 Update doc 2022-05-26 18:33:43 +02:00
Patrick Pelissier bd5d7aaada Fix wrong prototype in docs 2022-05-24 23:58:20 +02:00
Patrick Pelissier 18b6be8e00 Update doc 2022-05-24 23:56:34 +02:00
Patrick Pelissier 958abfef93 Make INIT_SET operator optional 2022-05-24 23:30:14 +02:00
Patrick Pelissier 198be1062b Update doc 2022-05-24 23:25:37 +02:00
Patrick Pelissier 0cfee02641 Make INIT operator optional 2022-05-24 23:22:36 +02:00
Patrick Pelissier 48dc38508a Factorize the documentation by using the generic interface (WIP) 2022-05-23 23:49:57 +02:00
Patrick Pelissier e763204bf7 Fix example 2022-05-22 22:54:25 +02:00
Patrick Pelissier 370baf56ab Factorize the documentation by using the generic interface (WIP) 2022-05-22 00:22:36 +02:00
Patrick Pelissier 4fd6bcbf99 Factorize the documentation by using the generic interface (WIP) 2022-05-19 22:41:19 +02:00
Patrick Pelissier 59d1e23dea Factorize the documentation by using the generic interface (WIP) 2022-05-19 22:28:53 +02:00
Patrick Pelissier cb173f2f81 Update doc 2022-05-19 21:45:16 +02:00
Patrick Pelissier d047174c2f Update doc 2022-05-19 21:43:42 +02:00
Patrick Pelissier df25159d03 Add generic interface chapter & start factorizing duplicate specification 2022-05-19 00:30:47 +02:00
Patrick Pelissier 99618a687e Update doc 2022-05-19 00:00:36 +02:00
Patrick Pelissier a1b226e185 Update doc 2022-05-16 23:37:04 +02:00
Patrick Pelissier e93df4332a Fix issue for 16 bits architecture 2022-05-14 09:16:41 +02:00
Patrick Pelissier 5a1f768b03 Update comment about lock-free property 2022-05-14 09:16:41 +02:00
Patrick Pelissier e854bc8fc9 Remove warning in C++ mode for using C++ class 2022-05-12 00:00:10 +02:00
Patrick Pelissier 9ab958708d Update doc:
clarify operators
2022-05-11 23:26:36 +02:00
Patrick Pelissier 85ea92d83b Review of m-core.h
* Add control of MSVC preprocessor
* Add comments
* Remove useless evaluation pass
* Rewrite some evaluation pass to be faster.
2022-05-11 21:38:47 +02:00
Patrick Pelissier 22a406ac51 Add new test case (M_MAP + M_SEQ) 2022-05-11 21:38:47 +02:00
Patrick Pelissier 58eed79413 Register the oplist associated to unsigned 2022-05-04 22:25:15 +02:00
Patrick Pelissier e83dea8212 Fix warnings for Visual C++ 2022-05-10 23:49:20 +02:00
Patrick Pelissier c829827f48 Fix warnings for Visual C++ 2022-05-10 23:34:48 +02:00
Patrick Pelissier b47cf05a59 Update doc 2022-05-10 23:14:47 +02:00
Patrick Pelissier 22a93514ff Add EMPLACE test for priority queue 2022-05-10 23:10:58 +02:00
Patrick Pelissier 154865f0f1 Add EMPLACE support for priority queue 2022-05-10 23:10:44 +02:00
Patrick Pelissier 71151770fd Fix wrong type 2022-05-09 22:55:57 +02:00
Patrick Pelissier 72623ce13e Adding test cases for I/O methods 2022-05-09 22:52:28 +02:00
Patrick Pelissier 94f20d56e9 Adding OUT_STR / IN_STR / PARSE_STR / GET_STR / IN_SERIAL / OUT_SERIAL methods 2022-05-09 22:51:46 +02:00
Patrick Pelissier 9e8ad9bfd9 Fix format 2022-05-09 22:48:56 +02:00
Patrick Pelissier e51a5be776 Add check of prioqueue against STL C++ 2022-05-09 22:25:09 +02:00
Patrick Pelissier 7d647340c6 Update 2022-05-09 22:24:48 +02:00
Patrick Pelissier c6ea3c0616 Fix spelling 2022-05-09 20:16:33 +02:00
Patrick Pelissier 9ab90be6d4 Add check of B+Tree / Set 2022-05-09 20:12:55 +02:00
Patrick Pelissier 10440320d1 Remove IT_REF from exported oplist as the items shall appear as not modifiable by algorithms 2022-05-09 20:12:39 +02:00
Patrick Pelissier fc7e93403a Update copyright year 2022-05-09 20:06:05 +02:00
Patrick Pelissier b0c4418584 Fix M_ALGO_EXTRACT: the source oplist wasn't transformed into a global one. 2022-05-09 20:03:26 +02:00
Patrick Pelissier 5f73eb7788 Add test for support C++ class in M*LIB 2022-05-06 23:08:27 +02:00
Patrick Pelissier a554312573 Update doc 2022-05-06 23:07:10 +02:00
Patrick Pelissier 8a1fd391d1 Fix reverse issue 2022-05-06 01:27:34 +02:00
Patrick Pelissier 95b104ee48 Issue in generation of functions:
if the method in the oplist uses API_* transformation,
if this method is a macro itself,
it may delay the expansion too much and
the macro may not be expanded at all in the final code generation.

Fix issue by adding a supplementary evaluation in the macro expansion.
Add test cases
2022-05-06 01:10:31 +02:00
Patrick Pelissier c3df69d011 Add tests for generic API + macros 2022-05-04 22:16:01 +02:00
Patrick Pelissier 73468a3e24 Update doc 2022-05-02 23:15:58 +02:00
Patrick Pelissier f254f98e42 Update doc 2022-05-02 21:40:49 +02:00
Patrick Pelissier d37076dd37 Update comments 2022-05-02 21:11:12 +02:00
Patrick Pelissier 5ef9376148 Improve example (adding ADD/SUB/MUL/DIV operators 2022-04-29 19:55:29 +02:00
Patrick Pelissier d8abda7583 Fix issue (implicit const cast) 2022-04-29 19:55:02 +02:00
Patrick Pelissier 892c755389 Improve example to show emplace support 2022-04-28 23:10:57 +02:00
Patrick Pelissier aba2f90c9d Add test for emplace generation for variant 2022-04-28 23:10:40 +02:00
Patrick Pelissier dc487c7e64 Add support for EMPLACE_TYPE for variant 2022-04-28 23:10:27 +02:00
Patrick Pelissier 18b1bd9518 Fix makefile if MPFR not found 2022-04-28 23:06:41 +02:00
Patrick Pelissier 845ab1fef0 Update comment 2022-04-28 23:03:04 +02:00
Patrick Pelissier 94bfac3f75 Improve example by adding also mpfr 2022-04-28 22:22:05 +02:00
Patrick Pelissier bd5c9ce2a7 Add MPFR detection 2022-04-28 22:10:36 +02:00
Patrick Pelissier f5934a6274 Add emplace type example 2022-04-27 21:57:28 +02:00
Patrick Pelissier c6f71fddc7 Add test for stable_sort 2022-04-26 21:35:51 +02:00
Patrick Pelissier 74764e2d6f Fix issues in stable_sort: wrong assertion & missing init_move 2022-04-26 21:35:51 +02:00
Patrick Pelissier 9b00a8c54e Update documentation 2022-04-25 22:10:19 +02:00
Patrick Pelissier 66735e99c3 Add check sanitize to Continuous Integration 2022-04-23 10:40:39 +02:00
Patrick Pelissier 80acbb4343 Ensure proper order of commands in case of parallelism 2022-04-23 10:37:42 +02:00
Patrick Pelissier 2fb912d43d Should remove warning with Visual C++ 2022-04-23 10:34:54 +02:00
Patrick Pelissier 8c8dc6de7c Add new example 2022-04-23 10:21:46 +02:00
Patrick Pelissier 677acdd14e Use of new M_INIT_EMPLACE_VAI macro 2022-04-23 10:21:33 +02:00
Patrick Pelissier 6caeea98b9 Add M_INIT_EMPLACE_VAI macro for INIT_WITH containers with emplace support 2022-04-23 10:21:17 +02:00
Patrick Pelissier c5d37ce028 Update comments 2022-04-23 10:03:51 +02:00
Patrick Pelissier 112b405df6 Reformat 2022-04-23 10:01:39 +02:00
Patrick Pelissier 47385d58e5 Update documentation with new generated functions 2022-04-23 09:20:11 +02:00
Patrick Pelissier c8275c8f63 Add test cases for generated emplace functions 2022-04-23 09:19:58 +02:00
Patrick Pelissier 0c1e888a78 Add emplace generation for RB Tree 2022-04-23 09:19:42 +02:00
Patrick Pelissier 6a1ff3e080 Add emplace generation for oplist with CMP operator 2022-04-23 09:18:20 +02:00
Patrick Pelissier 6d41eba5ed Update documentation for emplace functions 2022-04-22 22:51:45 +02:00
Patrick Pelissier c0abcc6d60 Add tests for new emplace functions 2022-04-22 22:51:36 +02:00
Patrick Pelissier da71c81195 Add emplace functions for list / deque 2022-04-22 22:51:17 +02:00
Patrick Pelissier 8e0d17e85c Add test for emplace string_t from const char * 2022-04-21 23:11:24 +02:00
Patrick Pelissier 6d98c273c1 Add EMPLACE_TYPE from const char * 2022-04-21 23:11:11 +02:00
Patrick Pelissier 85f6ff34aa Add test cases for generated emplace functions 2022-04-20 22:43:12 +02:00
Patrick Pelissier 759c24be63 Add request for generation for emplace functions 2022-04-20 22:43:12 +02:00
Patrick Pelissier d85955ef60 Add generation of emplace functions 2022-04-20 22:43:12 +02:00
Patrick Pelissier 3a53044198 Add M_EMPLACE macros to enables generic generation of EMPLACE functions 2022-04-20 22:43:12 +02:00
Patrick Pelissier 4d5cd9c635 Code generation shows no difference between && or & for simple & typical OOR values
So let's use the logical comparaison which is clearer.
2022-04-19 22:07:01 +02:00
Patrick Pelissier 57b88160ae Add asm generation for typical OOR_EQUAL_P functions 2022-04-19 20:57:03 +02:00
Patrick Pelissier 33ba602aef Reformat 2022-04-18 22:10:32 +02:00
Patrick Pelissier 3632388315 Reorder macros to group then by logical entity. Remove M_INVERT obsolete macro 2022-04-18 21:22:45 +02:00
Patrick Pelissier 6ee82e885b Update comments 2022-04-18 11:09:12 +02:00
Patrick Pelissier 2f92cee416 Update code for generated asm analysis 2022-04-18 11:08:59 +02:00
Patrick Pelissier 9269473e10 Remove M_APPLY_SIZEOF 2022-04-18 10:04:11 +02:00
Patrick Pelissier c8611ce708 Update comments 2022-04-18 09:44:13 +02:00
Patrick Pelissier d8fd43e9e9 Update comments & avoid using M_ID for internal macros 2022-04-18 09:41:43 +02:00
Patrick Pelissier a2e471620d Add support for '_' meta keyword 2022-04-18 09:24:32 +02:00
Patrick Pelissier ffa3821acf Add tests for M_KEYWORD_TO_VA_ARGS 2022-04-17 19:01:32 +02:00
Patrick Pelissier 5c98d47d8c Add M_KEYWORD_TO_VA_ARGS 2022-04-17 19:01:21 +02:00
Patrick Pelissier 0875eaac03 Add more tests 2022-04-17 18:51:27 +02:00
Patrick Pelissier 60734bdb2b Avoid using M_ID / M_OPFLAT in context where it could be used recursively 2022-04-15 23:44:07 +02:00
Patrick Pelissier e71b19424b Simplify definition of M_EMPTY_P & M_PARENTHESIS_P 2022-04-14 23:50:40 +02:00
Patrick Pelissier daac0169d5 Reformat 2022-04-14 23:47:11 +02:00
Patrick Pelissier baacc0df52 Add test cases for M_AND, M_OR, M_AND3 & M_OR3 2022-04-13 22:49:01 +02:00
Patrick Pelissier c6921536f7 Add M_AND3 & M_OR3 macros 2022-04-13 22:48:40 +02:00
Patrick Pelissier 4abf0ad2b2 Simplify code 2022-04-11 22:34:08 +02:00
Patrick Pelissier 379d555d35 Remove M_IF_DEFAULT1 from documentation 2022-04-10 23:12:32 +02:00
Patrick Pelissier 8c01acb8d2 Remove M_IF_DEFAULT1 (bad interface).
Fix warning in M_DEFAULT_ARGS in some cases.
2022-04-10 23:10:58 +02:00
Patrick Pelissier 2c2c3c21ba Add test for string_search in C11 2022-04-10 23:09:50 +02:00
Patrick Pelissier 50fd27e07b Use of M_DEFAULT_ARGS instead of M_IF_DEFAULT1 2022-04-10 23:09:29 +02:00
Patrick Pelissier 3309035814 Reducing preprocessing time for ALGO_FOR_EACH ALGO_TRANSFORM ALGO_EXTRACT 2022-04-10 11:28:12 +02:00
Patrick Pelissier b691758fa9 Update comments 2022-04-10 11:10:01 +02:00
Patrick Pelissier 7c9afcec8b Update vocabulary 2022-04-09 16:31:57 +02:00
Patrick Pelissier 06ac05526a Update doc 2022-04-09 09:02:26 +02:00
Patrick Pelissier 69cef8249a Update comments and move section 2022-04-09 00:11:51 +02:00
Patrick Pelissier 473df16a5a Update description & assertion of HASH functions 2022-04-08 23:38:33 +02:00
Patrick Pelissier e1abf0528c Rename M_DEFAULT_OPLIST in M_BASIC_OPLIST (cleaner name) 2022-04-08 22:54:29 +02:00
Patrick Pelissier ef0b335f67 Rename M_CHECK_DEFAULT_TYPE in M_CHECK_BASIC_TYPE, and makes it more stricter in C11. Start separating default macros from basic macros (that perform control & check) 2022-04-08 20:57:06 +02:00
Patrick Pelissier 1a866a3dc4 Update README 2022-04-08 20:55:35 +02:00
Patrick Pelissier ed437b9e05 Document SPMC & MPMC snapshots 2022-04-03 19:14:42 +02:00
Patrick Pelissier eea85872fd Simplify code 2022-04-03 19:14:25 +02:00
Patrick Pelissier 9d33e4cd5a Update name of library 2022-04-01 23:47:53 +02:00
Patrick Pelissier 530cc8d2a2 Update comments 2022-03-31 22:16:10 +02:00
Patrick Pelissier 9baca84825 Add operator EMPLACE_TYPE, to be used by future emplace methods 2022-03-30 23:11:07 +02:00
Patrick Pelissier 58538e4822 Fix spelling 2022-03-28 23:27:57 +02:00
Patrick Pelissier e31a8dc407 Update benchmark with new available specialized function 2022-03-26 16:09:25 +01:00
Patrick Pelissier 7875263092 Update documentation 2022-03-26 16:09:02 +01:00
Patrick Pelissier de3b8509bf Add tests for m_string_set_si & m_string_set_ui 2022-03-26 16:08:51 +01:00
Patrick Pelissier a19e1acfff Add function m_string_set_si & m_string_set_ui for converting an integer into a string. 2022-03-26 16:08:28 +01:00
Patrick Pelissier e613b5c624 Proper define of NDEBUG to avoid adding assertions in string benchmarks 2022-03-25 22:45:08 +01:00
Patrick Pelissier ccfddb0685 Update LIBSRT to be the source/build directory 2022-03-25 22:37:23 +01:00
Patrick Pelissier b8cd679679 Move generating macro into the m_ namespace and create a wrapper using historical names for compatibility with existing code 2022-03-24 20:46:49 +01:00
Patrick Pelissier fc26e472ab Move bitset functions to M* namespace 2022-03-23 22:39:18 +01:00
Patrick Pelissier fc8c7349d6 Reformat 2022-03-23 21:35:22 +01:00
Patrick Pelissier a4d9b8df17 Moving internal types to internal namespace 2022-03-22 23:37:35 +01:00
Patrick Pelissier f26da68aa4 Fix regression for C++ / CLANG 2022-03-21 23:27:37 +01:00
Patrick Pelissier 144182b540 Move the worker functions into the m_ namespace and create compatibility layer 2022-03-21 23:15:14 +01:00
Patrick Pelissier a834ca4921 Add missing public function 2022-03-21 23:13:34 +01:00
Patrick Pelissier d1fc216836 Move internal type to internal namespace 2022-03-20 19:02:01 +01:00
Patrick Pelissier 5e57338928 Rename string_ into m_string_ in header files (Test files still test classic API) 2022-03-20 18:30:32 +01:00
Patrick Pelissier f3376b6f0e Move internal functions to internal namespace 2022-03-20 11:50:05 +01:00
Patrick Pelissier 5e001fdd9d Move internal type to correct internal namespace 2022-03-19 17:01:20 +01:00
Patrick Pelissier 9fda06276c Move m_once_t to the public interface 2022-03-19 16:44:40 +01:00
Patrick Pelissier df79c306d9 Move the internal types toye the internal namespace 2022-03-19 16:44:18 +01:00
Patrick Pelissier e4955e6851 Move internal types to the internal namespace 2022-03-19 16:43:55 +01:00
Patrick Pelissier 0fec9e7ac4 Fix format 2022-03-19 11:46:28 +01:00
Patrick Pelissier 5be8bb435b Move WORKER_OPLIST to internal namespace 2022-03-19 11:44:58 +01:00
Patrick Pelissier 35b915ab10 Rename internal functions/types to the internal prefix 2022-03-19 10:47:27 +01:00
Patrick Pelissier 80c57e996d Add pottery string in bench 2022-03-19 08:32:10 +01:00
Patrick Pelissier 511293d580 Provide example of hash function 2022-03-17 23:03:04 +01:00
Patrick Pelissier fe2b816447 Add more example in C11 for showing more possibility 2022-03-17 19:37:12 +01:00
Patrick Pelissier 093b7dc1e8 Update example with new possibility & state of the art 2022-03-17 19:34:18 +01:00
Patrick Pelissier 811fa57cbc Fix generic API: remove the need of superfluous () 2022-03-17 19:33:46 +01:00
Patrick Pelissier 359ad20a6a Update documentation with generic API transformation 2022-03-16 22:44:19 +01:00
Patrick Pelissier ac9989e4ff Add generic API transformation
in the framework responsible of expanding
the call to a method from an operator.

The generic API transformation can
support a wide range of call
(Limited to 9 arguments maximum)
2022-03-16 22:29:57 +01:00
Patrick Pelissier 7268551737 Add micro utilities macros for handling list 2022-03-16 22:29:56 +01:00
Patrick Pelissier 823b1974bb Update comments 2022-03-16 22:29:56 +01:00
Patrick Pelissier 382f636206 Fix build issue of bench 2022-03-16 22:27:37 +01:00
Patrick Pelissier 9a1b4abcf9 Add missing small names 2022-03-15 19:29:18 +01:00
Patrick Pelissier a0fc57687b Fix format 2022-03-15 19:24:53 +01:00
Patrick Pelissier 02897f982f Add m_ prefix for the string API 2022-03-15 19:24:14 +01:00
Patrick Pelissier 07a5d0ed0a Define M_USE_SMALL_NAME user macro 2022-03-15 19:04:45 +01:00
Patrick Pelissier 017995ade6 Update README 2022-03-14 22:13:04 +01:00
Patrick Pelissier 9711b2280c Reorder the list of libraries in alphabetic order 2022-03-14 19:33:36 +01:00
Patrick Pelissier 619331916f Add reference to STR & POTTERY string libraries 2022-03-14 19:32:46 +01:00
Patrick Pelissier d7909f7312 Move internal function / macros with the m_string prefix to the internal m_str1ng prefix 2022-03-14 19:29:33 +01:00
Patrick Pelissier 22674f2b46 Fix format 2022-03-14 19:28:49 +01:00
Patrick Pelissier 845736c489 Fix format 2022-03-14 19:28:23 +01:00
Patrick Pelissier 501f9db465 Add bench of big dict for pottery 2022-03-14 19:08:27 +01:00
Patrick Pelissier 8dd440a582 Add note about the string_t format 2022-03-13 22:48:08 +01:00
Patrick Pelissier dd7f090b4b Add bench for POTTERY 2022-03-13 21:56:49 +01:00
Patrick Pelissier dc14a2677b Reformat & cleanup error messages 2022-03-13 21:10:07 +01:00
Patrick Pelissier 8b1ed7f0ae Fix help usage 2022-03-13 21:09:46 +01:00
Patrick Pelissier 19b01b404d Migrate to 2022 2022-03-12 20:25:45 +01:00
Patrick Pelissier ec780d2d4d Add POTTERY library reference 2022-03-12 20:20:45 +01:00
Patrick Pelissier 07790f6711 Add CPU information for MacOS 2022-03-12 20:09:59 +01:00
Patrick Pelissier f72d2b6c67 Add STC bench 2022-03-12 12:04:49 +01:00
Patrick Pelissier e35d631012 Fix path of MS Visual Studio 2022 2022-03-12 11:59:06 +01:00
Patrick Pelissier 3499a08207 Add support for MS Visual Studio 2022 2022-03-12 11:51:27 +01:00
Patrick Pelissier 0ac23e512e Fix CTL bench 2022-03-12 11:40:38 +01:00
PpHd 1852fabcd2 Merge pull request #98
Fix a few typos
2021-12-23 17:48:04 +01:00
Tim Gates 7b6bfac7cb docs: Fix a few typos
There are small typos in:
- example/ex-algo03.c
- m-algo.h
- m-core.h
- m-dict.h
- m-string.h

Fixes:
- Should read `occurrence` rather than `occurence`.
- Should read `fulfilled` rather than `fullfilled`.
- Should read `dictionaries` rather than `dictionnaries`.
- Should read `environment` rather than `environement`.
- Should read `unordered` rather than `undordered`.
2021-12-23 10:00:44 +11:00
Patrick Pelissier e72aa5fb79 Update doc 2021-12-03 22:59:33 +01:00
Patrick Pelissier f4b02b92cc Update documentation 2021-12-03 22:48:43 +01:00
Patrick Pelissier 39edcc560f Fix name of variable 2021-12-03 22:28:44 +01:00
Patrick Pelissier 50669a320c Add m_ prefix for GENINT module,
as it is purely internal (no need to prevent user space breakage).

It will put more stuff in the global m_ prefix
2021-12-03 22:08:15 +01:00
Patrick Pelissier d22c0b05ef Display CPU information 2021-12-03 21:50:36 +01:00
Patrick Pelissier 689be30803 Update README with an implicit constraint 2021-12-03 21:40:09 +01:00
Patrick Pelissier b393a83d38 Add example of JSON serialization on string 2021-12-03 21:39:41 +01:00
Patrick Pelissier 1a1339da6b Remove deprecated features 2021-11-20 13:05:50 +01:00
Patrick Pelissier 9926b51da0 Revert 829c20ba8 as there is an issue in calling M_KEYWORD_P within M_IF. 2021-11-20 10:15:31 +01:00
Patrick Pelissier 761447dea3 V0.6.1 2021-11-13 19:51:32 +01:00
Patrick Pelissier 829c20ba8a Update M_KEYWORD_P to support () . Add more recognized keywords (type, list, LIST, queue, QUEUE, INIT_WITH) 2021-11-13 19:51:23 +01:00
Patrick Pelissier 9ac734e191 Fix documentation 2021-11-12 20:03:36 +01:00
Patrick Pelissier 5420fc6c51 Fix documentation 2021-11-12 20:02:07 +01:00
Patrick Pelissier 62c8ac3e5d V0.6.0 2021-11-11 19:59:19 +01:00
Patrick Pelissier 1d7e93251c Fix overflow of one element in deque _remove 2021-11-11 19:59:19 +01:00
Patrick Pelissier 92fa4691d1 Add comment about the non presence of _it_remove 2021-11-09 21:20:16 +01:00
Patrick Pelissier a20fdf4713 Update documentation 2021-11-06 23:21:16 +01:00
Patrick Pelissier 570dedf1c3 Factorize _size & _empty_p for both dict 2021-11-06 13:54:17 +01:00
Patrick Pelissier 59e5c873ad Factorize _equal_p for both dict 2021-11-06 13:45:27 +01:00
Patrick Pelissier 8dbcdf9991 Uniformize field name between classic dict & OA dict 2021-11-06 13:38:49 +01:00
Patrick Pelissier cd43b50068 Fix name of method 2021-11-06 13:38:29 +01:00
Patrick Pelissier c0413a26f9 Add more example 2021-11-03 21:21:56 +01:00
Patrick Pelissier b2d3d86e0c Add alternative macro M_TEST_METHOD_ALTER_P 2021-11-03 20:54:03 +01:00
Patrick Pelissier bc7552f4a8 Update container summary 2021-11-03 20:53:31 +01:00
Patrick Pelissier 28ae13092f Workaround for MacOs special make 2021-11-02 18:42:41 +01:00
Patrick Pelissier 1f561da43f Add doc for deque _remove 2021-11-02 18:35:09 +01:00
Patrick Pelissier ef8dcda196 Add tests for deque _remove 2021-11-02 18:32:26 +01:00
Patrick Pelissier cf9eb892cf Update & finish deque _remove algorithm 2021-11-02 18:32:14 +01:00
Patrick Pelissier ffa1e2e59c Add WIP deque_remove method 2021-11-02 08:43:42 +01:00
Patrick Pelissier 9549e82b04 Remove launch of check-stl on MacOS as sanitizer=leak is not supported by clang on this system 2021-10-31 00:29:43 +02:00
Patrick Pelissier 50261e390e Update forgotten rename 2021-10-31 00:14:10 +02:00
Patrick Pelissier 618fc99cda Update Continuous Integration 2021-10-31 00:12:01 +02:00
Patrick Pelissier a9fc7e15f8 Rename GET_SET_KEY operator in SAFE_GET_KEY operator 2021-10-30 23:57:50 +02:00
Patrick Pelissier 6b064870f5 Rename CLEAN operator in RESET operator 2021-10-30 23:26:27 +02:00
Patrick Pelissier d78c50be3b Add new files in Makefile 2021-10-30 00:29:53 +02:00
Patrick Pelissier c96cea5a13 Port the examples to rename _get_at to _safe_get 2021-10-30 00:17:15 +02:00
Patrick Pelissier 51d4e930f5 Rename the suffix _get_at to the _safe_get suffix
(Better & clearer naming of the function)
2021-10-30 00:04:07 +02:00
Patrick Pelissier e650addfe4 Replace _clean into _reset (Fix issues for C11 build) 2021-10-28 18:42:15 +02:00
Patrick Pelissier 30afcb45d8 Replace _clean into _reset 2021-10-28 18:32:53 +02:00
Patrick Pelissier e10c3586a3 Rename BITSET & CONCURRENT _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 18:13:00 +02:00
Patrick Pelissier 836d892832 Rename BUFFER, I-LIST, PRIOQUEUE & SHARED _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 18:08:07 +02:00
Patrick Pelissier 826d251ffe Rename RBTREE & BPTREE _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:55:54 +02:00
Patrick Pelissier 510cd062ba Rename DICT, TUPLE & VARIANT _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:51:17 +02:00
Patrick Pelissier 2695cd6f3e Rename DEQUE _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:40:56 +02:00
Patrick Pelissier f6e3cbbb65 Rename LIST _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:38:18 +02:00
Patrick Pelissier f172bbaad2 Rename ARRAY _clean in _reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:32:02 +02:00
Patrick Pelissier 9176953a8e Rename string_clean in string_reset to avoid confusing _clean & _clear functions. See #97 2021-10-28 17:27:41 +02:00
Patrick Pelissier ae6b87d646 Optimization in case of small constant strings 2021-10-24 21:48:02 +02:00
Patrick Pelissier f719b2387a Remove file 2021-10-14 21:28:26 +02:00
Patrick Pelissier 5bfa8321d0 Add check dict-set against STL 2021-10-14 21:26:02 +02:00
Patrick Pelissier e99fd23e69 Don't export IT_REF for DICT_SET as they should not be updated directly by algorithm 2021-10-14 21:23:37 +02:00
Patrick Pelissier 5057366fb2 Update documentation for RBTREE _remove 2021-10-10 20:36:02 +02:00
Patrick Pelissier 44801b8b91 Add more tests for _remove (that triggered an issue in _previous) 2021-10-10 20:35:44 +02:00
Patrick Pelissier 9eabc86bdd Fix issue in _next / _previous in some corner cases. Fix issue in _remove (IT was not updated to next item) 2021-10-10 20:35:18 +02:00
Patrick Pelissier fbc8f407eb Add test for method _remove 2021-10-10 10:18:06 +02:00
Patrick Pelissier 09a8b93634 Add method _remove for RBTREE 2021-10-10 10:17:55 +02:00
Patrick Pelissier 2caa7b77e7 Add check of RBTREE 2021-10-10 10:04:48 +02:00
Patrick Pelissier c057247126 Add missing exported method 2021-10-10 10:01:44 +02:00
Patrick Pelissier 0899be21c3 Add support for seed (set/random) for rand 2021-10-10 09:36:35 +02:00
Patrick Pelissier c29c9f9ccd Remove obsolete UPDATE operator 2021-10-09 17:57:49 +02:00
Patrick Pelissier c12f698f32 Restore exe target 2021-10-09 17:27:53 +02:00
Patrick Pelissier d6a8a6d159 Add test for _reserver and _resize 2021-10-09 17:25:43 +02:00
Patrick Pelissier 7bf325f91a Update recent framework to compute dependencies 2021-10-09 17:25:13 +02:00
Patrick Pelissier fdfff0c5c5 Add framework to test containers againts C++ library 2021-10-09 16:55:51 +02:00
Patrick Pelissier 4409f613e0 Add test more complete cases for the last issue 2021-10-09 10:11:27 +02:00
Patrick Pelissier 9de644b0f3 Fix issue in _pop_front & _front method that corrupts the deque in some cases 2021-10-09 10:11:02 +02:00
Patrick Pelissier 3e36363d28 Fix format 2021-10-09 10:08:13 +02:00
Patrick Pelissier 4f1d1a949c Document _get_at method for dict 2021-10-08 20:47:18 +02:00
Patrick Pelissier e52f3b8b30 Add more test cases for deque _next / _previous 2021-10-07 21:47:49 +02:00
Patrick Pelissier 36916e7b3d Fix issue in deque _next and deque _previous methods in some corner cases 2021-10-07 21:47:20 +02:00
Patrick Pelissier ba778e9bd2 Simplify 2021-10-07 21:40:42 +02:00
Patrick Pelissier df7112489a Add tag for identifying C code in documentation 2021-10-05 00:28:31 +02:00
Patrick Pelissier d9c203736f Update examples section 2021-10-04 20:36:39 +02:00
Patrick Pelissier 2b61ffa784 Ignore backup files 2021-10-02 19:15:03 +02:00
Patrick Pelissier ba85640172 Add bench for CTL library 2021-10-02 19:14:01 +02:00
Patrick Pelissier 4d21ad5050 Update 2021-10-02 19:13:10 +02:00
Patrick Pelissier aae14de62b Update documentation 2021-10-02 13:22:12 +02:00
Patrick Pelissier 70fa621745 Add test function for _splice function 2021-10-02 13:09:51 +02:00
Patrick Pelissier e97f4f7f41 Document _splice function for dictionary 2021-10-02 13:09:18 +02:00
Patrick Pelissier 7a08ddce9e Remove UPDATE opertor as there are no default operators that define it (and no one uses it as it is poorly documented). Replace by SET for RB-THREE. Replace by ADD for the splice function of dictionary 2021-10-02 13:06:30 +02:00
Patrick Pelissier e19c9d31a8 Update comments 2021-10-01 07:41:23 +02:00
Patrick Pelissier 51ae5f9f0c Fix spelling 2021-10-01 07:41:11 +02:00
Patrick Pelissier 22e8133f95 Test for corrected issue of IT_INSERT (Wrong behavior if IT==END) 2021-09-29 23:30:20 +02:00
Patrick Pelissier c2e19fed01 Fix issue in IT_INSERT (Wrong behavior if IT==END) 2021-09-29 23:29:57 +02:00
Patrick Pelissier 274afc9978 Fix syntax 2021-09-24 23:26:23 +02:00
Patrick Pelissier 0c337836ca Add CTL library as reference 2021-09-24 23:23:57 +02:00
Patrick Pelissier 1a3e694e20 Add new example of different containers 2021-09-23 23:06:24 +02:00
Patrick Pelissier a0572b63b1 Update documentation for tuple 2021-09-23 23:04:10 +02:00
Patrick Pelissier 1765d8ef06 Update test for testing new possibility of the tuples 2021-09-23 23:04:00 +02:00
Patrick Pelissier 1e00a102e8 TUPLE: Defined HASH/CMP/EQUAL methods if at least ONE methods is defined in the fields. Fields that don't have or have disabled method are supposed to be secondary fields that are not pertinent for comparing the objects. 2021-09-23 23:03:30 +02:00
Patrick Pelissier 61f8dcdbae Add string_set_char function 2021-09-22 23:07:35 +02:00
Patrick Pelissier 39eeb3aec7 Fix buffer overflow in ARRAY _pop_at function (reported by tyrone718) 2021-09-18 09:52:33 +02:00
Patrick Pelissier 2178dcfcab Add LIST_INIT_VALUE & LIST_DUAL_PUSH_INIT_VALUE. 2021-08-15 21:55:09 +02:00
Patrick Pelissier f8b4f44105 Add ARRAY_INIT_VALUE 2021-08-15 21:44:36 +02:00
Patrick Pelissier 9c2468c2b7 Update comments. 2021-08-15 21:27:54 +02:00
Patrick Pelissier 3d5cc55d0a Adding assembly generation for mserial-json
in order to check proper & full inlining.
2021-08-09 10:30:53 +02:00
Patrick Pelissier 5b9cccd2dd Adding more macros not to be expanded in coverage mode 2021-08-09 10:30:04 +02:00
Patrick Pelissier 103b2ab79b Fix C++ 32 bits error on Ubuntu. 2021-08-07 17:15:45 +02:00
Patrick Pelissier 05f1cd784c Add support of GCC Static Analyzer
It seems to report only false positive.
2021-08-07 17:07:38 +02:00
Patrick Pelissier 6e6754f84e Activate tests for C++ 32 bits. 2021-08-07 10:28:19 +02:00
Patrick Pelissier 33ef448a86 Update documentation. 2021-08-07 10:27:56 +02:00
Patrick Pelissier 8ce59c2e9d Maintenance:
* update comments
* simplify code.
2021-08-07 00:34:18 +02:00
Patrick Pelissier 85a363d325 Update definition of returned iterator of _it_from of RB tree
from the greatest element of 'rbtree' lower of equal than 'data'
to the lowest element of the tree 'rbtree' greater or equal than 'data'

It is more logical and natural:
if you have a tree of elements between [2, 4], and you want
to iterate all elements from 0 to 10, the old definition doesn't allow
you to iterate easily over this subset.
2021-07-16 22:46:44 +02:00
Patrick Pelissier 7dc1a9dc0e Update RB Tree:
* Fix issue of the searched element is the root node (See #93)
for _it_from. It now returns a proper iterator.

* Update _it_from to match the last documentation:
if there is no element lower or equal to the searched node,
it returns a null iterator.

* Update _it_while_p so that it returns false if it is null iterator.
2021-07-16 21:47:37 +02:00
Patrick Pelissier 983d90b731 * Complete tests on iterators to be more exhaustive.
* Add tests on _it_from/_it_until_p/_it_while_p.
2021-07-16 21:46:57 +02:00
Patrick Pelissier f307762801 Update document of _it_from, _it_until_p, _it_while_p:
* _it_from: if there is no element that matches the condition,
it returns a null iterator, which is more coherent.
* _it_until_p: clarify condition if the iterator is null.
* _it_while_p: clarify condition if the iterator is null.
2021-07-16 21:42:55 +02:00
Patrick Pelissier 7924798e7a Update names of contract macros as per macro renaming 2021-07-16 21:41:59 +02:00
Patrick Pelissier e46bbaffb9 Avoid GCC warning (-Wstringop-truncation) 2021-07-05 23:14:21 +02:00
Patrick Pelissier 0171c49413 Unlikely some if conditions. 2021-07-05 22:45:57 +02:00
Patrick Pelissier a79cd9da97 Fix issue for RB Tree _it_equal_p method
if both iterators are equal and are associated
to a RB tree without any element.
2021-07-05 22:44:58 +02:00
Patrick Pelissier 408959c927 Be more precise in the bound check. 2021-07-05 22:32:19 +02:00
Patrick Pelissier ac4d93fe29 Clean RB Tree _pop_at to avoid an aliasing issue. 2021-07-05 20:21:26 +02:00
Patrick Pelissier 82d224fa66 Clean up documentation 2021-07-05 20:19:00 +02:00
Patrick Pelissier a5b6d8e391 Rewrite assertion to be more robust. 2021-07-04 00:20:10 +02:00
Patrick Pelissier 7f79abec3f Fix issue with INIT_WITH of array/list/....
combined with tuple:
_push_back_raw was used within an expanded macro
and as a consequence was expanded multiple times,
resulting in adding a new term in the sequence
for each field of the tuple.
2021-07-04 00:01:00 +02:00
Patrick Pelissier ca8d4aa97a Update _back & _front to return a modifiable ptr
(There is no real reasons to return a const pointer).
2021-07-03 23:59:19 +02:00
PpHd 690cef561c Merge pull request #92 from P-p-H-d/let-recur
Recursive INIT_WITH within M_LET
2021-07-01 22:33:34 +02:00
Patrick Pelissier 16ac4c556b Update documentation. 2021-07-01 22:14:17 +02:00
Patrick Pelissier 3c175b9199 Update documentation. 2021-07-01 22:12:15 +02:00
Patrick Pelissier a3827cc384 Add tests for new constructs
allowed in M_LET for tuples
2021-07-01 22:12:15 +02:00
Patrick Pelissier 353daecbd1 Comment new code. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 368392fb8f Add CLEAN operator for default oplist
(same as INIT operator)
2021-07-01 22:12:15 +02:00
Patrick Pelissier 57441b2fc1 Add first draft of recursive
INIT_WITH macro for tuples.
2021-07-01 22:12:15 +02:00
Patrick Pelissier b225600238 Add internal functions for tuple
that are needed for future INIT_WITH support.
2021-07-01 22:12:15 +02:00
Patrick Pelissier 6b361e0d0c Add use of M_PRINT in C11 mode. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 08668aa02b Add a new example of the new M_LET feature. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 3d3eb6f1d2 Update tests to new syntax of M_LET. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 9bd820c652 Force use of INIT_WITH for function object. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 0e960ec23f Force use of INIT_WITH within M_LET. 2021-07-01 22:12:15 +02:00
Patrick Pelissier ca65d81b60 * Fix conflict between M_MAP2 /M_MAP2B
(this arises through M_LET & M_GET_METHOD)

* Rename M_GET_OPPROPERTY into M_GET_PROPERTY

* M_LET can be configured to always use INIT_WITH for special kind of objects.
2021-07-01 22:12:15 +02:00
Patrick Pelissier 23624a1d73 Remove M_EVAL from M_LET as it is not needed anymore. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 3ac08b0395 Add test with a lot of different kind of M_LET with list of strings. 2021-07-01 22:12:15 +02:00
Patrick Pelissier dedb79dbc5 Use of new initializer macro 2021-07-01 22:12:15 +02:00
Patrick Pelissier 154b503bc6 Avoid using the input more than once in macros string_init_* (Avoid issues) 2021-07-01 22:12:15 +02:00
Patrick Pelissier 5c612ce521 Update M_LET to handle both set & init_with depending on the user syntax. Add M_INIT_WITH_VAI to use this new feature. 2021-07-01 22:12:15 +02:00
Patrick Pelissier 80582ac5ce Update as the minimum level of recursion is decreased 2021-07-01 22:12:15 +02:00
Patrick Pelissier 8e6af3bfeb Add note 2021-07-01 22:12:15 +02:00
Patrick Pelissier 61671d1b18 Minor fix 2021-07-01 22:12:15 +02:00
Patrick Pelissier aa3ad973d0 Add another recussive M_LET test 2021-07-01 22:12:15 +02:00
Patrick Pelissier a19a010d1e Add WIP version for a M_LET recursive 2021-07-01 22:12:14 +02:00
Patrick Pelissier 36003b6bb3 * Add support for extented variable for M_[F]PRINT
* Update documentation
* Add test.
2021-07-01 00:13:31 +02:00
Patrick Pelissier 3c83e4088c Add internal macro M_MERGE_ARGLIST 2021-06-20 11:06:19 +02:00
Patrick Pelissier 357feb9532 Update documentation as per lastest changes. 2021-06-19 22:47:13 +02:00
Patrick Pelissier 7e234cba65 Add test of M_FPRINT using string_t. 2021-06-19 22:46:58 +02:00
Patrick Pelissier 0535ceeaeb Add support of string_t by M_PRINT macro. 2021-06-19 22:46:41 +02:00
Patrick Pelissier e688f0b1df Add internal method M_GET_OPPROPERTY to get the subproperty of an oplist
Add test for such macro
Rename operator CLASS into PROPERTIES
2021-06-17 00:20:35 +02:00
Patrick Pelissier a950e15625 Adding method for NAME operator for basic containers 2021-06-12 11:11:30 +02:00
Patrick Pelissier cf8b198dac Fix issue in M_LET: if the INIT/INIT_SET/INIT_WITH uses the macro M_IF, it may be not expanded in some cases (since the M_CALL_* is used itself within an expanded tainted M_IF). Fix this by calling M_CALL_* outside the expanded M_IF. 2021-05-23 00:53:54 +02:00
Patrick Pelissier c75d5da02d Fix: use of M_CALL_INIT / M_CALL_CLEAR instead of M_GET_INIT / M_GET_CLEAR so that API transformation can be applied 2021-05-23 00:42:43 +02:00
Patrick Pelissier cdffb15066 Simplify code 2021-05-23 00:34:08 +02:00
Patrick Pelissier cd0ad0dba9 Factorize code 2021-05-23 00:31:23 +02:00
Patrick Pelissier d3be5dba96 Reduce number of created threads, as sometimes it hits the limits 2021-05-22 18:11:09 +02:00
Patrick Pelissier cb94a26a9f Update documentation 2021-05-22 17:33:46 +02:00
Patrick Pelissier 3c8b238e75 Add operator CLASS and new keywords 2021-05-22 17:33:34 +02:00
Patrick Pelissier 74202d52b3 Adding default value for LIMITS
enabling to avoid defining then for all types.
2021-04-16 23:23:42 +02:00
Patrick Pelissier 603c92cd0e Cleanup uneeded final comma separator 2021-04-10 23:27:49 +02:00
Patrick Pelissier e514d74f43 Update test to be more pertinent 2021-04-04 22:28:32 +02:00
Patrick Pelissier 970161464a Add constraint 2021-04-04 22:28:13 +02:00
Patrick Pelissier 3e7de27c00 Rename M_HASH_SEED into M_USE_HASH_SEED
as it a user overridable macro
(API break).
2021-04-03 23:15:12 +02:00
Patrick Pelissier e28d403216 Undo previous changes until further analysis (it broke CI) 2021-03-28 11:53:18 +02:00
Patrick Pelissier fdeb9f1322 Format 2021-03-28 11:48:59 +02:00
Patrick Pelissier 76fad21103 Update comments and naming 2021-03-28 11:48:59 +02:00
Patrick Pelissier 5d4fa31083 Update doc & comments 2021-03-28 11:48:58 +02:00
Patrick Pelissier c3858f4e63 Update documentation 2021-03-28 11:48:58 +02:00
Patrick Pelissier 2e0fc21878 Fix _push_move of SPSC. It shall take a pointer to the object, not the object itself as argument, just like the other _push_move 2021-03-28 11:48:58 +02:00
Patrick Pelissier 4b71bbec7e Protect key from being changed while iterating. 2021-03-28 11:13:55 +02:00
Patrick Pelissier 052989a5a2 Update m_serial_ll_ct to have more basic types. 2021-03-28 11:09:59 +02:00
Patrick Pelissier 60cfc63c4e Add static assertion. 2021-03-28 09:39:52 +02:00
Patrick Pelissier 60ef4c7f06 Fix documentation 2021-03-28 09:39:41 +02:00
Patrick Pelissier 58fc40d0f1 Update oplist 2021-03-28 09:32:23 +02:00
Patrick Pelissier 3d7e9e7c03 Add _get_at method for B+TREE 2021-03-28 09:29:04 +02:00
Patrick Pelissier 52e745f905 Update documentation of operators 2021-03-27 21:15:03 +01:00
Patrick Pelissier 8433fc178c Fix issue for union with visual & clang-cl 2021-03-20 13:16:10 +01:00
Patrick Pelissier 59807baa18 Fix several minor issues on m-buffer:
1) Fix performance issue if the buffer was not designed
to be thread safe. The internal numbers are in this cases
just plain numbers and not atomic numbers. This is done
through union. Fix #90

2) In case of thread safe buffer, put each item in a
separate cacheline. This ensures proper performance in
case there is several producers. This however
increases the consumption size.

3) Fix a data race issue: after the mutex is locked,
and before the test if the buffer is empty (through the
atomic read of its size). It is solved by performing a
memory acquire when testing if the buffer is empty.

4) Add more comments.
2021-03-20 13:01:51 +01:00
Patrick Pelissier 9b5b15e8cb Update comment 2021-03-16 21:43:09 +01:00
Patrick Pelissier 2c54b63c51 Update dev doc 2021-03-16 21:42:48 +01:00
Patrick Pelissier e4d1167274 Improve test suite to be more representative 2021-03-14 23:42:05 +01:00
Patrick Pelissier 2f10aba390 Workaround issue with address sanitizer 2021-03-14 21:26:04 +01:00
Patrick Pelissier a044fadec8 Fix minor warning in some compiler options 2021-03-14 11:00:05 +01:00
Patrick Pelissier 0edb6165b5 Fix buffer overflow if size=64*N 2021-03-13 23:39:26 +01:00
Patrick Pelissier 7d262f2450 Fix formatting 2021-03-13 23:08:04 +01:00
Patrick Pelissier fa30328572 Reduce allowed range for buffer to unsigned int. It should be more than enough for any scenario. 2021-03-13 22:43:01 +01:00
Patrick Pelissier b0cff7c6ac Remove git checkout HEAD^2 as per recommendation of CodeQL 2021-03-09 22:39:02 +01:00
Patrick Pelissier 50da9e803c Add documentation for m_serial_str_json 2021-03-09 22:12:44 +01:00
Patrick Pelissier 26252fedf5 Add test for JSON serialization over string 2021-03-09 22:12:29 +01:00
Patrick Pelissier 2dcda90c7b Add JSON serial over string 2021-03-09 22:12:16 +01:00
Patrick Pelissier b7d79c0a83 Fix issue for wrong formatted JSON (error not properly reported) 2021-03-09 20:56:13 +01:00
Patrick Pelissier ae285c0a01 Add also const string in serial object 2021-03-09 20:55:46 +01:00
Patrick Pelissier 07db846f3b Rename internal string functions to be compliant with new scheme. Not sure if this scheme will remain however (still searching for a better naming that fits all criteria). 2021-03-01 22:18:32 +01:00
Patrick Pelissier 3b6907b743 Add more test cases. 2021-02-23 16:24:46 +01:00
Patrick Pelissier 82e49c6214 Clarify doc. 2021-02-23 16:03:03 +01:00
Patrick Pelissier 8e9aa9cac4 Fix _min & _max for B+Tree
Make code match the documentation if there is no element in the tree.
2021-02-23 15:59:45 +01:00
Patrick Pelissier 5cd6c1dd36 Update Makefile by controlling when making dist that all files are properly referenced in the Makefile 2021-02-22 18:59:49 +01:00
Patrick Pelissier a98ce5ea91 Remove unused test file 2021-02-22 18:59:49 +01:00
Patrick Pelissier a4bb0fab8f Update documentation for bitset 2021-02-22 12:06:51 +01:00
Patrick Pelissier 7b2e242c94 Add function bitset_popcount 2021-02-22 12:06:46 +01:00
Patrick Pelissier 5fd6352a4e Add more tests for bitset_resize 2021-02-22 11:40:29 +01:00
Patrick Pelissier a82f2ba065 * Fix an issue in _pop_at. * Optimize code by ensuring that the last limbs is always properly masked (simplify algorithm) 2021-02-22 11:31:49 +01:00
Patrick Pelissier 3377acd9e6 Test another bit for _pop_at 2021-02-22 11:30:59 +01:00
Patrick Pelissier 709168652a Reformat and specify clz for bitset size = 0 2021-02-21 21:41:51 +01:00
Patrick Pelissier e25e9ba29b Make the contract of Array & Buffer fail after a clear. 2021-02-21 21:08:35 +01:00
Patrick Pelissier ed5eac6e9d Update doc 2021-02-21 21:08:35 +01:00
Patrick Pelissier 651768f012 Fix name in doc 2021-02-21 21:08:35 +01:00
Patrick Pelissier 88c0a881da Update 2021-02-20 00:22:24 +01:00
Patrick Pelissier 5b9dd504e5 Add chapter "Global User Customization" 2021-02-20 00:20:54 +01:00
Patrick Pelissier 165ec09061 Rename user customizable macros
to be compliant with other
and clearer that they can be customized.
2021-02-20 00:10:26 +01:00
Patrick Pelissier 6cc972bab2 Rename header define to be compliant with others. 2021-02-20 00:08:07 +01:00
Patrick Pelissier 333047fc4c Make assertions more robust.
Fix read out of bound (with test cases).
2021-02-14 00:15:43 +01:00
Patrick Pelissier 3e4a5932c2 Rename internal function / types.
Reformat
2021-02-13 11:45:16 +01:00
Patrick Pelissier e2f6b81a03 Remove M_LOCK from readme as it is obsolete. 2021-02-13 11:45:16 +01:00
Patrick Pelissier 0231aad947 Update coding rules. 2021-02-13 11:45:16 +01:00
Patrick Pelissier 6636800c5b Remove obsolete / deprecated function/macros. 2021-02-13 11:45:16 +01:00
Patrick Pelissier d1f41de0cb Rename internal functions
to use internal prefix.
2021-02-13 11:45:16 +01:00
Patrick Pelissier c4d339cb62 Rename internal interface. 2021-02-13 11:45:16 +01:00
Patrick Pelissier 56b2adc57d Fix internal name. 2021-02-13 11:45:16 +01:00
Patrick Pelissier a73bee2650 Micro-optimization of DICT_OA
by reducing the number of cmp instructions.
2021-02-13 11:45:16 +01:00
Patrick Pelissier 517da1b999 Rename generated internal functions
to avoid "poluting" userspace naming.
2021-02-13 11:45:05 +01:00
Patrick Pelissier 25497bd96f Factorize code so that _DEF macros use _DEF_AS ones 2021-02-07 23:04:59 +01:00
Patrick Pelissier d12b1edc39 Update doc 2021-02-07 23:04:45 +01:00
Patrick Pelissier 0515cfd068 Add macro M_GREATER_THAN_P & M_LESS_OR_EQUAL_P (src, tests, doc) 2021-02-07 09:53:13 +01:00
Patrick Pelissier e84bc9fc0d Fix link 2021-02-07 09:41:10 +01:00
Patrick Pelissier d85df43329 Replace UNERDLOW/OVERFLOW by M_UNDERFLOW/M_OVERFLOW as some systems (Windows/MacOS) perform '#define UNDERFLOW value' in their headers, preventing the detection at preprocessing time. 2021-02-07 09:36:00 +01:00
Patrick Pelissier 16e2e07d41 * Fix M_REVERSE as per the doc (don't add parenthesis on the returned arglist). * Update usage to take this into account. 2021-02-07 00:50:10 +01:00
Patrick Pelissier 57fcb4012b Update doc 2021-02-07 00:42:10 +01:00
Patrick Pelissier 5be981def3 Fix warning 2021-02-07 00:41:59 +01:00
Patrick Pelissier 493e38abfc Fix formatting 2021-02-07 00:31:15 +01:00
Patrick Pelissier 6e006d216b Add macro M_GREATER_OR_EQUAL_P (src, test, doc) 2021-02-07 00:25:47 +01:00
Patrick Pelissier da613ad188 * Add macro M_LESS_THAN_P (src, test, doc). * Robustify M_INC & M_DEC so that overflow & underflow keeps returning overflow & underflow 2021-02-07 00:10:55 +01:00
Patrick Pelissier 3dad326bea Update doc 2021-02-06 23:54:16 +01:00
Patrick Pelissier 480a791f4c Update tests 2021-02-06 23:41:04 +01:00
Patrick Pelissier 753c46ef14 Add OrderPP 2021-02-06 23:40:58 +01:00
Patrick Pelissier f2d5de252b Add M_FILTER and M_FILTER_C macros (src, tests, doc) 2021-02-06 23:24:55 +01:00
Patrick Pelissier 0cb1a8054f Add M_REPLICATE & M_REPLICATE_C (src, test, doc) 2021-02-06 22:32:38 +01:00
Patrick Pelissier 07eb5697ab Remove limitation of M_AS_STR to be called within a M_APPLY 2021-02-06 22:22:50 +01:00
Patrick Pelissier e4dc06a0e2 Update doc 2021-02-06 22:13:06 +01:00
Patrick Pelissier cd2012f33d Update doc 2021-02-06 21:58:52 +01:00
Patrick Pelissier 9eba30648d Rename M_INVERT into M_REVERSE to be more coherent with REVERSE operator 2021-02-06 21:58:45 +01:00
Patrick Pelissier 7e70371197 Format & comment code 2021-02-06 21:28:18 +01:00
Patrick Pelissier 527f6d8d9a Add metalang99 2021-02-06 21:05:26 +01:00
Patrick Pelissier 9ebc12a98f Update to 0.5.1 2021-02-06 21:03:19 +01:00
Patrick Pelissier bb21d9a6ad Update Makefile to control that both versions are the same when making a distribution 2021-02-06 21:00:25 +01:00
Patrick Pelissier ad39cdd393 Add some tests for new function 2021-02-05 00:17:18 +01:00
Patrick Pelissier 0de771036b Add M_REDUCE3
Add M_MAP3_C
Add operator LIMITS.
2021-02-05 00:11:44 +01:00
Patrick Pelissier 6d6afa4cfd Update doc 2021-01-29 20:43:46 +01:00
Patrick Pelissier 7546cbedd2 Update doc 2021-01-20 20:44:48 +01:00
Patrick Pelissier 8d5962eefd Update target html & doc 2021-01-20 20:44:36 +01:00
Patrick Pelissier 8597b0b8c0 Fix warning on clang and old gcc 2021-01-18 18:21:01 +01:00
Patrick Pelissier c625c39883 Add a new implementation of M_CSTR using GNU C extension which provides faster & smaller code 2021-01-18 18:16:45 +01:00
Patrick Pelissier bce86460fe Rewrite test cases to avoid potential warnings 2021-01-18 18:16:05 +01:00
Patrick Pelissier f002eebc83 Update constraint 2021-01-18 18:01:42 +01:00
Patrick Pelissier 139da2e49f Update example 2021-01-16 10:25:55 +01:00
Patrick Pelissier 91d40a0f43 V0.5.0 2021-01-13 20:18:01 +01:00
Patrick Pelissier 25fe26deaa Happy new year 2021-01-13 20:18:01 +01:00
Patrick Pelissier cd357c5eb7 Rewrite the wrappers of strncpy & strncat:
Add one argument about the allocation of the dest buffer
Theses wrappers are internal (so no impact to API)
and only used in a few place in m-string.
This make the wrappers able to use the function
strncpy_s & strncat_s for MSVC rather than using
reimplementation of the original functions.
2021-01-13 08:34:47 +01:00
Patrick Pelissier 561f67b3b9 Update list of ignored files 2021-01-13 08:27:00 +01:00
Patrick Pelissier 15a02e3306 Update final message 2021-01-10 20:04:14 +01:00
Patrick Pelissier 944d29e8bc Workaround CLANG preprocessor failure on Windows platform 2021-01-10 20:03:28 +01:00
Patrick Pelissier aefba70c1e Rework once again how to detect a failure in an application:
IF errorlevel 1 only works for positive error code
  IF not errorlevel 0 only works for negative error code
There are not reliable. So, use && and || instead.

Remove expected failure on test as all tests pass now
(and it was broken).
2021-01-10 18:08:48 +01:00
Patrick Pelissier c9ed4ba820 Fix compiler error with MSVC with new implementation of offsetof 2021-01-10 18:01:19 +01:00
Patrick Pelissier df97ea848c Fix error for C++ 2021-01-10 10:01:54 +01:00
Patrick Pelissier 93d810421d Fix warning with newest gcc 2021-01-10 09:57:07 +01:00
Patrick Pelissier f560839516 Add example of string_sets 2021-01-10 09:51:53 +01:00
Patrick Pelissier 8a9d5f6a00 Add macro string_sets (like string_cats) 2021-01-10 09:51:38 +01:00
Patrick Pelissier 5f05c1e169 Make stdarg an optional header. Some works remain to do to make stdio fully optional 2021-01-10 09:40:37 +01:00
Patrick Pelissier 3df2408ffb Add macro M_CSTR 2021-01-10 09:26:27 +01:00
Patrick Pelissier ffc2ec8c4b Fix format 2021-01-10 09:25:27 +01:00
Patrick Pelissier b0ebbb306e Update 2021-01-10 09:20:42 +01:00
Patrick Pelissier c3574aa290 Update comments 2021-01-10 09:02:52 +01:00
Patrick Pelissier eabc867c2a Rename used namespace for C++ to m_lib 2021-01-10 08:48:46 +01:00
Patrick Pelissier a03b2e80c6 Document string_cats 2021-01-07 22:13:10 +01:00
Patrick Pelissier c4f23640d5 Add test for string_cats 2021-01-07 22:13:10 +01:00
Patrick Pelissier a42b854f14 Add macro string_cats to concat multiple strings 2021-01-07 22:13:10 +01:00
Patrick Pelissier 9aa08bfc59 Add support for struct in M_AS_TYPE 2021-01-07 22:13:10 +01:00
Patrick Pelissier 06b79a6caa Add tests for M_AS_TYPE 2021-01-07 22:13:10 +01:00
Patrick Pelissier 6d533bd52a Add (internal) macro M_CONDITIONAL 2021-01-07 22:13:10 +01:00
Patrick Pelissier 1b4c608087 Rename operator TEST_EMPTY into EMPTY_P to be compliant with iterator operator 2021-01-07 22:13:10 +01:00
Patrick Pelissier 6ccc81fd92 Remove unused operator UPDATE_TYPE 2021-01-07 22:13:09 +01:00
Patrick Pelissier 6f7d3fcd79 Add limiation on M_EMPTY_P 2020-12-31 00:12:36 +01:00
Patrick Pelissier 7484dee707 Fix a corner case for M_EMPTY_P where it performs too much evaluation steps 2020-12-31 00:12:21 +01:00
Patrick Pelissier a580aaac83 Add more test cases for M_EMPTY_P 2020-12-31 00:11:37 +01:00
Patrick Pelissier 52bef353e0 Workaround WIN clang that claims to be C11 but fails to deliver a working assert.h (See #85) 2020-12-30 19:03:10 +01:00
Patrick Pelissier 826ecf76c0 Workaround a compiler warning 2020-12-30 19:02:00 +01:00
Patrick Pelissier 2cf5bff32d Fix negative error code termination for MSVS (See #86) 2020-12-30 17:58:43 +01:00
Patrick Pelissier 1377d7a1c2 Fix usage of strncpy_s and strncat_s
Provides a full wrapper around strncpy & strncat
(for MSVS as it complains on using strncpy & strncat).
See #86
2020-12-28 23:35:50 +01:00
Patrick Pelissier ab9284ca20 Update documentation 2020-12-27 10:44:41 +01:00
Patrick Pelissier 5dab01c1c7 Fix spelling 2020-12-26 09:08:42 +01:00
Patrick Pelissier f9c434401b Fix M_GET_STRING_ARG (See #84) 2020-12-26 09:00:39 +01:00
Patrick Pelissier 76b9f9a715 Add test cases for M_GET_STRING 2020-12-26 08:58:52 +01:00
Patrick Pelissier 2ee82c478b Remove useless type (see #82) 2020-12-24 10:58:51 +01:00
Patrick Pelissier 211121435d Fix warning in C++ mode with G++ 10 2020-12-24 08:13:44 +01:00
Patrick Pelissier fffd1702a5 CLANG 3.8 stdatomic works. Update minimun version 2020-12-24 07:35:45 +01:00
Patrick Pelissier 9aa99bf230 Update package list before installing multilib 2020-12-21 15:23:49 +01:00
Patrick Pelissier 1671ca8d67 Add more assertions 2020-12-21 15:16:16 +01:00
Patrick Pelissier ad16b310e1 Fix overflow issue in bitset_last_p (see #81) 2020-12-21 15:08:19 +01:00
Patrick Pelissier 4dbcfd25b3 Fix non support of break in M_LET_IF 2020-12-16 15:27:41 +01:00
Patrick Pelissier 01167b09c4 Add an example of M_LET_IF 2020-12-16 11:07:11 +01:00
Patrick Pelissier 15d0b86c62 Update documentation & add tests as per lastest changes 2020-12-16 11:07:11 +01:00
Patrick Pelissier edbcecb272 Add support for else condition in M_LET_IF. Fix also a bug in computing unique variable per line 2020-12-16 11:07:11 +01:00
Patrick Pelissier 1689db7b9c Fix spelling 2020-12-16 11:07:11 +01:00
Patrick Pelissier f5bc8796f7 Add functions:
* string_vprintf
* string_init_vprintf
2020-12-15 22:14:43 +01:00
Patrick Pelissier e893560a48 Add macros M_LET_IF and M_DEFER to help handling with runtime errors 2020-12-14 21:26:07 +01:00
Patrick Pelissier a4ff7c71f2 Update documentation 2020-12-13 00:18:53 +01:00
Patrick Pelissier 9f780805f0 Update 2020-12-10 07:59:28 +01:00
Patrick Pelissier 749273d1bb Update list of methods 2020-12-06 08:32:54 +01:00
Patrick Pelissier d8fd2e3e69 Update doc as per latest changes 2020-12-06 00:16:53 +01:00
Patrick Pelissier d443a84254 Remove deprecated funtion 2020-12-06 00:15:17 +01:00
Patrick Pelissier ef614b19ee Fix ISO C warning. 2020-12-05 18:33:26 +01:00
Patrick Pelissier 1c5c4aa50f Fix compatibility with C++
which doesn't support designated init.
2020-12-05 18:28:30 +01:00
Patrick Pelissier 5533ffffaa Add tests for intrusive shared pointers. 2020-12-05 18:14:38 +01:00
Patrick Pelissier 34c990e259 Add function _init_once for intrusive shared pointer 2020-12-05 18:14:22 +01:00
Patrick Pelissier 5f0b6b9f26 Fix format 2020-12-05 12:42:45 +01:00
Patrick Pelissier 26eb882a30 Rename tuple function :
* _init_set2 in _init_emplace
* _set2 in _emplace
due to better & clearer naming.
(API break)
2020-12-05 12:29:20 +01:00
Patrick Pelissier 4d0e799c7a Remove obsolete function. 2020-12-05 12:27:33 +01:00
Patrick Pelissier 6801f688a4 Clarify atomic thin layer limitation (see #79) 2020-12-01 07:27:14 +01:00
Patrick Pelissier bdf29af9e9 * Add DJB Xor hash * Rename function (see #78) 2020-11-29 22:05:24 +01:00
Patrick Pelissier 79dabfc52f Update documentation as per #76 2020-11-29 20:34:05 +01:00
Patrick Pelissier de2268c406 Factorization of comparaison by using memcmp 2020-11-29 20:06:56 +01:00
Patrick Pelissier 85ea1f40dc Use classic hash rather than fast one for C-String (fix assertion failure for C-String hash) 2020-11-29 19:36:28 +01:00
Patrick Pelissier f89ba94689 Add test for computing C-string hash (raise assertion failure) 2020-11-29 19:35:52 +01:00
Patrick Pelissier 0279dcc3cc Fix issue on MacOS 2020-11-25 22:56:51 +01:00
Patrick Pelissier 62c8e005bb Add a new example of array of strings. 2020-11-25 22:41:25 +01:00
Patrick Pelissier 2a28f8d407 Add string_init_printf 2020-11-25 22:41:11 +01:00
Patrick Pelissier 9802fc5098 Remove rapidstring as it is no longer maintained, and the author deleted the repository. 2020-11-24 23:04:33 +01:00
Patrick Pelissier f372a72fd8 Update list of libraries 2020-11-23 20:29:30 +01:00
Patrick Pelissier 9d661852b2 Factorization of replace_all function for all libraries 2020-11-23 20:14:17 +01:00
Patrick Pelissier b343d356c3 Add support for empty replaced string 2020-11-22 23:29:38 +01:00
Patrick Pelissier 2e4404ca7e Fix a (strange) warning for gcc 8 without assertions.
Add back the assertions as compile hints.
2020-11-22 23:20:04 +01:00
Patrick Pelissier 29eebaf38d Factorization of the allocation. 2020-11-22 23:11:09 +01:00
Patrick Pelissier d0d69aebfa Add final null char in computation of the needed size for the new function _replace_all 2020-11-22 23:09:37 +01:00
Patrick Pelissier 477c5853f1 Update bench to use new function. 2020-11-22 23:04:50 +01:00
Patrick Pelissier 55e7b3083a Add function string_replace_all[_str]
to replace all occurences of a string by another.
2020-11-22 23:04:32 +01:00
Patrick Pelissier 0b9e27fb7f Add note on 32 bits systems where atomic library is needed 2020-11-21 11:45:25 +01:00
Patrick Pelissier 36ac6d5104 Fix issue on single core system 2020-11-21 10:53:11 +01:00
Patrick Pelissier d898d6d4cc Remove duplicate function 2020-11-21 10:26:02 +01:00
Patrick Pelissier e7388929c4 Migrate to msys2 v2 for github actions. 2020-11-19 22:43:05 +01:00
Patrick Pelissier 45f8b31efc Add function string_subset 2020-11-19 22:31:33 +01:00
Patrick Pelissier ebf440731d Fix address sanitizer issue 2020-11-15 09:43:41 +01:00
Patrick Pelissier 501a4a65ec Add test cases 2020-11-15 09:39:29 +01:00
Patrick Pelissier 800d03f728 Update documentation. 2020-11-15 09:39:15 +01:00
Patrick Pelissier 19ff6bfeac Add equal_p method for m-prioqueue 2020-11-15 09:39:01 +01:00
Patrick Pelissier 24f5739a3b Update documentation. 2020-11-14 23:56:28 +01:00
Patrick Pelissier b658598e02 Update documentation for _update & _erase of priority queues. 2020-11-14 23:48:46 +01:00
Patrick Pelissier 47343a2893 Add proper test cases for _update of priority queue 2020-11-14 23:48:23 +01:00
Patrick Pelissier c1f99359be Fix issue in update of priority in priority queue:
* Rename _update_further into _update.
* it now supports increase or decrease of priority.
* _update_further is deprecated (and was broken).
2020-11-14 23:48:08 +01:00
Patrick Pelissier bd89e162fc Add support for additional parameter id 2020-11-14 23:45:38 +01:00
Patrick Pelissier 983a63fbbc Add more comments to explain how it works. 2020-11-14 22:45:39 +01:00
Patrick Pelissier 978e0ea5d7 Fix format 2020-11-14 22:45:18 +01:00
Patrick Pelissier 85c4b50b6f Improve coverage of prioriy queue. 2020-11-08 01:00:17 +01:00
Patrick Pelissier e77aec4619 Reduce test case for MacOS / MINGW (returning incorrect return value for printf) 2020-11-05 23:33:26 +01:00
Patrick Pelissier d67e084010 Fix introduced warning 2020-11-05 22:55:03 +01:00
Patrick Pelissier b0a74f162e Fix string_printf in case of error in formating. 2020-11-05 22:51:28 +01:00
Patrick Pelissier d92126b97e Add more tests (improve coverage) 2020-11-05 22:51:02 +01:00
Patrick Pelissier c055358fa2 Reformat 2020-11-05 22:50:38 +01:00
Patrick Pelissier 9f89148b69 Remove valgrind
(not working in Multithread code)
2020-11-05 22:02:44 +01:00
Patrick Pelissier ef1145603a Update comments. 2020-10-31 17:30:14 +01:00
Patrick Pelissier d169a06f79 Rename STRING_ASSERT_SLOW into M_ASERT_SLOW 2020-10-31 17:30:14 +01:00
Patrick Pelissier 8e15a8cfe9 Fix warnings of CodeQL 2020-10-31 00:35:28 +01:00
Patrick Pelissier 6466cefbf4 Fix yml syntax 2020-10-31 00:17:13 +01:00
Patrick Pelissier bec9a897c9 Update codeql to use test executable 2020-10-31 00:13:03 +01:00
Patrick Pelissier 37d47cb0f1 Cleanup static analyser 2020-10-31 00:12:40 +01:00
Patrick Pelissier 0854136005 Add target exe for analyser
Cleanup of static analyzer
2020-10-31 00:12:02 +01:00
Patrick Pelissier 9427931e45 Add CodeQL in continuous integration backend 2020-10-31 00:01:05 +01:00
Patrick Pelissier 6aa28b4cfe Fix warnings on ARM 2020-10-30 08:02:37 +01:00
Patrick Pelissier a29682ca29 Create M_ASSERT macro to encapsulate assert within M*LIB
The goal is to enable the user to override this macro if needed so that it can enable or disable the M*LIB witout impacting its own assertions.
2020-10-29 22:46:17 +01:00
Patrick Pelissier f5afd6e275 Update comments. 2020-10-25 21:16:43 +01:00
Patrick Pelissier 7b5fd14bcf Update comment. 2020-10-24 23:29:02 +02:00
Patrick Pelissier 22ce001f03 Remove incorrect use of M_ASSUME by assert 2020-10-24 23:14:14 +02:00
Patrick Pelissier 6f761091cc Update comment. 2020-10-24 23:07:29 +02:00
Patrick Pelissier bb9e0e4f6e Adding test for M_LET for bounded string 2020-10-24 14:03:31 +02:00
Patrick Pelissier 5e658a81fe Adding INIT_WITH support for bounded string within M_LET 2020-10-24 14:03:27 +02:00
Patrick Pelissier ddc722bf78 Add FIXME 2020-10-23 21:50:57 +02:00
Patrick Pelissier 0818d0ac7c Fix macro formatting. 2020-10-23 21:46:34 +02:00
Patrick Pelissier 2f315793cd Use of M_ASSERT_INDEX for deque 2020-10-23 21:45:37 +02:00
Patrick Pelissier 067a034bc9 Use of M_ASSERT_INDEX for list. 2020-10-23 21:39:33 +02:00
Patrick Pelissier 201cc45fd8 Use of M_ASSERT_INDEX for bitset. 2020-10-23 21:37:44 +02:00
Patrick Pelissier 7a270ffacb Update documentation 2020-10-23 21:32:06 +02:00
Patrick Pelissier 27bb62533a Use of M_ASSERT_INDEX
to validate user input.
2020-10-21 23:57:52 +02:00
Patrick Pelissier 032388b790 Update message 2020-10-21 23:57:24 +02:00
Patrick Pelissier f1e2f81e79 Improve formating of macros:
if the line is too long
and can be reduced,
reduce it.
2020-10-21 23:56:55 +02:00
Patrick Pelissier 54d4b80368 Reformat macro to 80 characters 2020-10-21 23:23:40 +02:00
Patrick Pelissier 8a0a556604 Add utility to reformat automatically
macro to 80 characters.
2020-10-21 23:23:16 +02:00
Patrick Pelissier 895f362628 Fix a majorant stack usage of B+TREE 2020-10-17 22:46:43 +02:00
Patrick Pelissier d24b52586d Put a type within internal namespaces. 2020-10-17 22:25:22 +02:00
Patrick Pelissier d76585cb0e Update test as per latest changes. 2020-10-17 22:25:05 +02:00
Patrick Pelissier fb44be6efe Remove argument itret_t from *SET_DEF_AS
as it is useless
(Return type IS the key type for a set).
2020-10-17 22:24:53 +02:00
Patrick Pelissier 0b6a5aaa97 Port to last API version of CMC 2020-10-17 20:14:06 +02:00
Patrick Pelissier c00fdc65a2 Change installation directory
so that all M*LIB headers are in one directory.
2020-10-17 13:22:17 +02:00
Patrick Pelissier ab7490eb8a Fix list of distributed files. 2020-10-17 13:17:47 +02:00
Patrick Pelissier 1a46c0cd3f Clarify should usage in the documentation. 2020-10-17 13:07:41 +02:00
Patrick Pelissier 22f595c015 Update comment 2020-10-17 12:39:09 +02:00
Patrick Pelissier 68c76ad146 Update example with latest changes. 2020-10-16 21:59:53 +02:00
Patrick Pelissier 0b18792b96 Document _DEF_AS macros
Fix #60
2020-10-16 21:56:42 +02:00
Patrick Pelissier 464e8e5f8f Clean usage of 'shall' within the documentation. 2020-10-16 21:33:01 +02:00
Patrick Pelissier 45410f3f0c Update README. 2020-10-16 21:04:07 +02:00
Patrick Pelissier 556e706343 Update doc as per last rename 2020-10-16 21:01:41 +02:00
Patrick Pelissier 1e534bd307 Rename derefence type of an iterator of a dict or a B+Treee into _ittref_t. 2020-10-16 21:01:29 +02:00
Patrick Pelissier 7a517ee3ae Upate comments. 2020-10-16 20:53:34 +02:00
Patrick Pelissier 9bb1957afa Rename internal types. 2020-10-16 20:51:24 +02:00
Patrick Pelissier 86f942ee5f Fix forgotten external type in internal function. 2020-10-15 22:15:01 +02:00
Patrick Pelissier a23df528e4 Add DICT_*_AS macros. 2020-10-15 22:05:18 +02:00
Patrick Pelissier 0e9af6dfac Prepare user name integration for OA dictionnaries. 2020-10-15 21:53:11 +02:00
Patrick Pelissier 99a8db1111 Prepare integration for custom names for dict. 2020-10-15 21:41:53 +02:00
Patrick Pelissier 24cdf1ca5c Use of internal types within the code
instead of external ones.
2020-10-03 16:07:32 +02:00
Patrick Pelissier f1b794b239 Use of external documented type
instead of internal type.
2020-10-03 16:07:14 +02:00
Patrick Pelissier b4fdcbc547 Factorization of the it_deref name for overloading 2020-10-03 15:48:44 +02:00
Patrick Pelissier ce9986f6d8 Factorization of common pattern for bucket dictionnaries. 2020-10-03 14:47:47 +02:00
Patrick Pelissier ad4dcae1db Add macro VARIANT_DEF2_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier b3fa63c971 Factorization of name usage 2020-10-03 14:07:14 +02:00
Patrick Pelissier 364101592b Remove unused file 2020-10-03 14:07:14 +02:00
Patrick Pelissier 5b89196cd7 Add macro TUPLE_DEF2_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier feb8b30048 Factorization of M_C(name, _t) 2020-10-03 14:07:14 +02:00
Patrick Pelissier 8340cf70fb Add macros
FUNC_OBJ_ITF_DEF_AS
FUNC_OBJ_INS_DEF_AS
2020-10-03 14:07:14 +02:00
Patrick Pelissier affb3778a0 Rename internal types to _ct 2020-10-03 14:07:14 +02:00
Patrick Pelissier c039f07f2d Add macros
BPTREE_DEF2_AS
BPTREE_DEF_AS
BPTREE_MULTI_DEF2_AS
BPTREE_MULTI_DEF_AS
2020-10-03 14:07:14 +02:00
Patrick Pelissier c180981768 Add macros
CONCURRENT_DEF_AS
CONCURRENT_RP_DEF_AS
2020-10-03 14:07:14 +02:00
Patrick Pelissier 2cfac5c332 Fix build issue in C11 for new macros. 2020-10-03 14:07:14 +02:00
Patrick Pelissier 8ba489eef3 Add macros
SNAPSHOT_SPSC_DEF_AS
SNAPSHOT_SPMC_DEF_AS
SNAPSHOT_MPMC_DEF_AS
2020-10-03 14:07:14 +02:00
Patrick Pelissier a4cb6e3681 Add macros SHARED_PTR_DEF_AS, SHARED_PTR_RELAXED_DEF_AS, SHARED_RESOURCE_DEF_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier 379e0be211 Use of new macro to define internal types not exported. 2020-10-03 14:07:14 +02:00
Patrick Pelissier acb886c391 Add macro RBTREE_DEF_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier 7f26ef0f1c Add new macros to define container
with the full given name.
2020-10-03 14:07:14 +02:00
Patrick Pelissier 1d8e541205 Add macros BUFFER_DEF_AS, QUEUE_MPMC_DEF_AS, QUEUE_SPSC_DEF_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier a4fa70a478 Add macro DEQUE_DEF_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier 3d3a473716 Add macro ILIST_DEF_AS 2020-10-03 14:07:14 +02:00
Patrick Pelissier e04b120d41 Add new macros _DEF_AS so that
user can define its own name for the generated types.
2020-10-03 14:07:14 +02:00
Patrick Pelissier 63eee6bba3 Update comments 2020-10-03 14:07:14 +02:00
Patrick Pelissier b396b42808 Update comments 2020-10-03 14:07:14 +02:00
Patrick Pelissier eb8b106f48 Update comments. 2020-10-03 14:07:14 +02:00
Patrick Pelissier 5d144991cb Reformat & add more assertions. 2020-10-03 14:07:14 +02:00
Patrick Pelissier 35718ae551 Rename type as internal types 2020-10-03 14:07:14 +02:00
Patrick Pelissier 1dd9aff402 Factorize the name of the object at top level. 2020-10-03 14:07:14 +02:00
Patrick Pelissier 6d47074457 Rename internal types of m-core 2020-10-03 14:07:14 +02:00
Patrick Pelissier 1943650ca3 Factorization of the name of the object
at the top level to be able to create
new high level macros that enables
to select the full name of the type.
2020-10-03 14:07:14 +02:00
Patrick Pelissier 5722f19939 Update comments 2020-10-03 14:07:14 +02:00
Patrick Pelissier 7cf14b5d8a Update formatting 2020-10-03 14:07:14 +02:00
Patrick Pelissier b3a1a75f6f Rename internal types:
a suffix ending with _ct means confidential type
ans is reserved for M*LIB internal usage.

OPLIST doesn't use the external types
but rather the internal types.
It enables to be independent of the real names
of the external types.
Such external names are planned to be fully customizable
(i.e. the user may define a name that suits its coding style)
2020-10-03 14:07:14 +02:00
Patrick Pelissier eb7556f88f Replace abort by assert for static analyszer 2020-08-22 18:58:48 +02:00
Patrick Pelissier 805c747c60 Add more assertions (help static analyzer) 2020-08-22 18:54:51 +02:00
Patrick Pelissier 5f9feb833c Replace TAB by SPACE 2020-07-25 19:17:25 +02:00
Patrick Pelissier efef35c1e1 Reformat 2020-07-25 18:20:17 +02:00
Patrick Pelissier b1b32f565d Transform TAB into SPACE. 2020-07-25 18:15:57 +02:00
Patrick Pelissier f4cd8eaff9 Rename internal macro to TUPLEI_ 2020-07-25 18:01:34 +02:00
Patrick Pelissier 2cd5258f89 Add comments
Replace TAB by SPACE.
2020-07-25 17:54:01 +02:00
Patrick Pelissier 1b206931df Transform TAB into SPACE 2020-07-22 20:51:45 +02:00
Patrick Pelissier f68840ef8c Update doc 2020-07-19 01:12:12 +02:00
Patrick Pelissier 779c15ec08 Update tests as per new semantics 2020-07-19 01:11:15 +02:00
Patrick Pelissier 29bcc00202 Update format 2020-07-19 01:06:48 +02:00
Patrick Pelissier 1ff0d9fac0 Add test for _sort_intersect 2020-07-19 01:01:53 +02:00
Patrick Pelissier 4488853642 Factorization of _sort_union 2020-07-19 00:59:11 +02:00
Patrick Pelissier d5dc5d083d Fix _sort_union bug 2020-07-19 00:55:51 +02:00
Patrick Pelissier 784c42d850 Update _insert functions to update
iterators as per new specification.
2020-07-19 00:55:35 +02:00
Patrick Pelissier 8c1eb1fcb5 Add tests for _sort_union 2020-07-19 00:53:58 +02:00
Patrick Pelissier 49180bfbe5 Add documentation on IT_INSERT operator 2020-07-19 00:53:43 +02:00
Patrick Pelissier a3116dd813 Update comments 2020-07-18 09:54:12 +02:00
Patrick Pelissier 23df465401 Update comments 2020-07-14 14:44:10 +02:00
Patrick Pelissier 966170452f Improve test representativity by simulating various speeds for readers and writers 2020-07-14 14:43:14 +02:00
Patrick Pelissier eaf7ae7dee Fix spelling 2020-07-14 00:47:25 +02:00
Patrick Pelissier 8a6652646a Fix formatting (Replace TAB with SPACE) 2020-07-14 00:34:59 +02:00
Patrick Pelissier 2063bf879d Formatting: replace TAB by SPACE. 2020-07-14 00:26:26 +02:00
Patrick Pelissier 2529d4ae49 Update comments & remove warning about _Atomic 2020-07-12 22:52:36 +02:00
Patrick Pelissier 439bc06423 Fix unused value warning 2020-07-12 00:32:09 +02:00
Patrick Pelissier ab6c90f42f Fix issue with a warning that it triggers now but now before, whereas the code has not changed. Another random warning 2020-07-11 20:39:27 +02:00
Patrick Pelissier ac9e9a83b9 Fix issue with warnings on MacOS 2020-07-11 20:38:51 +02:00
Patrick Pelissier e495b92ae5 Workaround warnings about unused return value 2020-07-11 20:29:55 +02:00
Patrick Pelissier 50b1bedc54 Workaround some warnings 2020-07-11 20:13:31 +02:00
Patrick Pelissier 4a80ccd5f4 Add optimization to enable more warnings 2020-07-11 20:13:13 +02:00
Patrick Pelissier 6ca65dd60c Update comment 2020-07-11 18:36:46 +02:00
Patrick Pelissier b2be4d5397 Improve checking of failure detection 2020-07-11 18:02:27 +02:00
Patrick Pelissier de34cefa83 add test for detecting call to disable method 2020-07-11 18:02:11 +02:00
Patrick Pelissier 40c8dbae1e Update detection of disabled method 2020-07-11 18:01:48 +02:00
Patrick Pelissier 18af53cf38 Disable Wformat-nonliteral in the protected section 2020-07-11 17:18:43 +02:00
Patrick Pelissier 8510318ba5 Another minor warning about casting a double into a float 2020-07-11 17:17:59 +02:00
Patrick Pelissier 6ad02ffe56 Stop on warnings for CI 2020-07-11 16:57:03 +02:00
Patrick Pelissier 535e45d564 Update flags 2020-07-10 13:00:07 +02:00
Patrick Pelissier e2c60aa45c Fix another warnings that are triggered in another random combinaison of compiler settings 2020-07-10 12:59:31 +02:00
Patrick Pelissier 56d2a74818 Fix some warnings 2020-07-09 23:38:34 +02:00
Patrick Pelissier 8a36b5ff15 Workaround to avoid CLANG unused function warnings 2020-07-09 22:14:00 +02:00
Patrick Pelissier 7607645636 Reeanble Wunused-function 2020-07-09 22:13:24 +02:00
Patrick Pelissier cbb84accfe Add build on linux 32 bits 2020-07-09 17:31:16 +02:00
Patrick Pelissier 3e70cf7b5f TCC doesn't support -MM, so use cc to generate them 2020-07-09 10:45:09 +02:00
Patrick Pelissier 1a7deef735 Add TCC target 2020-07-09 10:38:35 +02:00
Patrick Pelissier 748771ab72 Update comment 2020-07-09 10:37:37 +02:00
Patrick Pelissier 6ef279dd2f Add comments 2020-07-07 18:30:14 +02:00
Patrick Pelissier abcf37dc72 Update 2020-07-07 13:07:54 +02:00
Patrick Pelissier 690b7bf9c1 Fix other warning for msys2 2020-07-05 23:53:06 +02:00
Patrick Pelissier 71cec5155a Fix uncompliant m-atomic support
if __STDC_NO_ATOMICS__ is defined, then in C11, there is no stdatomic header
2020-07-04 23:34:24 +02:00
Patrick Pelissier d2b0873a95 Add missing make for msys2 2020-07-04 23:09:37 +02:00
Patrick Pelissier 4cecdbb93e Add missing packages for msys2 as per https://www.msys2.org/docs/ci/ 2020-07-04 23:01:47 +02:00
Patrick Pelissier 2abca7d244 Update command line for msys2 as per https://www.msys2.org/docs/ci/ 2020-07-04 22:58:16 +02:00
Patrick Pelissier c26b467e86 Update command line for msys2 2020-07-04 22:48:41 +02:00
Patrick Pelissier 19514b09b0 Add msys2 target 2020-07-04 22:34:07 +02:00
Patrick Pelissier ab98577deb Fix warning 2020-07-04 12:50:34 +02:00
Patrick Pelissier aae5f00dbd Add new benchmark 2020-07-04 00:47:06 +02:00
Patrick Pelissier 04706d48b9 Fix further warnings 2020-07-03 23:03:12 +02:00
Patrick Pelissier c7df60c78d Fix some warnings 2020-07-03 22:44:34 +02:00
Patrick Pelissier f03a4503eb Fix some warnings 2020-07-03 22:15:54 +02:00
Patrick Pelissier a6951fe5e3 Fix warnings for clang-cl 2020-07-03 21:59:25 +02:00
Patrick Pelissier 6def48a0d1 Fix clang-cl to target x64 mode 2020-07-03 21:30:19 +02:00
Patrick Pelissier 8b5d1e07ce Fix build with MSVC in 32 bits mode 2020-07-03 21:25:20 +02:00
Patrick Pelissier 3182c39280 Add clang-cl in the continuous Integration 2020-07-03 21:18:17 +02:00
Patrick Pelissier e0b5dc2f02 Add test for clang-cl 2020-07-03 20:59:42 +02:00
Patrick Pelissier 6e5181e405 Fix doc on B+TREE 2020-07-02 23:22:44 +02:00
Patrick Pelissier 75f4f23144 Add comments and fix Pn level 2020-07-02 21:41:57 +02:00
Patrick Pelissier bc1402f66a Udpate documentation 2020-07-02 10:40:41 +02:00
Patrick Pelissier fc5ffcb404 Update API 2020-07-02 10:39:22 +02:00
Patrick Pelissier bd20a021ce Update documentation 2020-07-02 10:39:15 +02:00
Patrick Pelissier dfd12107de Add new function _clear_ptr 2020-07-02 10:39:05 +02:00
Patrick Pelissier 6743cb9456 Add posibility for user to select Thread backend directly 2020-07-02 00:09:54 +02:00
Patrick Pelissier 4aa93325e9 Update documentation 2020-07-01 12:08:24 +02:00
Patrick Pelissier f2a06ede62 Add mechanism to disable temporary compiler warnings in a sequence of code. 2020-07-01 11:47:55 +02:00
Patrick Pelissier a36752b8ce Update documentation (Fix #66) 2020-07-01 11:45:24 +02:00
Patrick Pelissier 3b347f2ba5 Reduce some warnings using the atomic compatibility layer (cannot fix all) 2020-07-01 11:06:58 +02:00
Patrick Pelissier 47296e5c11 The user can define M_USE_C11_NO_THREADS to disable C11 header (Support for broken C11 implementation) 2020-06-29 21:53:09 +02:00
Patrick Pelissier a24c530ec6 Update documentation on _init_new method 2020-06-29 16:03:54 +02:00
Patrick Pelissier 7ebe0608ae Define _init_new method only if NEW method has not been disabled 2020-06-29 16:03:38 +02:00
Patrick Pelissier 2a3021c021 Adding more code generation. 2020-06-29 16:01:38 +02:00
Patrick Pelissier 4d313aa72b Fix warning about unused function 2020-06-29 15:16:37 +02:00
Patrick Pelissier 7906a39647 Fix warning about unused function 2020-06-29 15:16:03 +02:00
Patrick Pelissier 86254958f0 Add precision on C11 thread layer (#65) 2020-06-29 15:02:34 +02:00
Patrick Pelissier 0089c1af61 Remove clang-cl as it is not available 2020-06-28 23:08:44 +02:00
Patrick Pelissier 6b5a3ddef7 Add clang-cl version 2020-06-28 23:04:06 +02:00
PpHd 42c2fd69a2 Merge pull request #64 from vladipus/patch-2
Update m-core.h
2020-06-27 21:12:44 +02:00
Vladislav Dmitrievich Turbanov bcb9b831db Update m-core.h
A tiny typo. MSVS should be referred to as MSVC - that is the standard way.
2020-06-27 19:08:52 +03:00
Patrick Pelissier f6483cbb30 It seems GNUC is force to 4 for APPLE/CLANG 2020-06-27 01:00:46 +02:00
Patrick Pelissier f742707699 Always use atomic in C++ 2020-06-27 00:31:58 +02:00
Patrick Pelissier aee02d86ab Workaround issue with CLANG++ on MAC 2020-06-27 00:10:40 +02:00
Patrick Pelissier dfbf34daf6 Remove a warning with some compiler by encoding 0 as UINT_MAX+1 2020-06-26 23:48:59 +02:00
Patrick Pelissier 494cbbecf0 Try to make Apple Make working in C11 mode 2020-06-26 23:40:49 +02:00
Patrick Pelissier a1513777f1 Activate C++ build too 2020-06-26 23:38:54 +02:00
Patrick Pelissier 9784a16d47 Get ride of modular arithmetic 2020-06-26 00:25:15 +02:00
Patrick Pelissier a8648e0cc1 Fix variable name for conditional code 2020-06-25 23:49:28 +02:00
Patrick Pelissier 3f8e93ad7a Use of intrinsic for clz within MSVS 2020-06-25 23:45:39 +02:00
Patrick Pelissier b040bc411f Add tests for builtin core functions 2020-06-25 23:35:34 +02:00
Patrick Pelissier ae8c3e5300 Update documentation about array & mandatory operators 2020-06-25 22:49:54 +02:00
Patrick Pelissier 01d390c3e9 Test array without INIT_SET & SET 2020-06-25 22:49:36 +02:00
Patrick Pelissier 56e4cda76c Make INIT_SET & SET operators of arrays as optional 2020-06-25 22:49:25 +02:00
Patrick Pelissier c59d585c22 Add new macro to test method1 or method2 in oplist 2020-06-25 22:49:08 +02:00
PpHd 81c97682a7 Merge pull request #62 from vladipus/patch-1
Update README.md
2020-06-25 21:21:18 +02:00
Patrick Pelissier a432628df6 Fix warnings for CLANG/WINDOWS (#61) 2020-06-25 21:18:01 +02:00
Vladislav Dmitrievich Turbanov d16effb4c5 Update README.md
Fixed a small typo in the ALGO_DEF example, that features an ARRAY_OPLIST with `int` instead of `array_int`
2020-06-25 22:13:53 +03:00
Patrick Pelissier 6279f98bb5 Run also in C11 mode for CI 2020-06-24 21:15:51 +02:00
Patrick Pelissier 3cbc474e76 Document M_ENUM_OPLIST 2020-06-24 21:14:00 +02:00
Patrick Pelissier c80fb7bebe Add test for M_ENUM_OPLIST (in particular I/O tests) 2020-06-24 21:13:43 +02:00
Patrick Pelissier 68788a6fb8 Add M_ENUM_OPLIST 2020-06-24 21:13:13 +02:00
Patrick Pelissier fd3cb50249 Remove temporary file 2020-06-22 00:38:19 +02:00
Patrick Pelissier 7e0bd8414d Fix warnings for mingw 2020-06-22 00:33:10 +02:00
Patrick Pelissier 70de571dc8 Fix warnings in test suite. 2020-06-22 00:14:55 +02:00
Patrick Pelissier cc6da8941c * Fix wanings for reduce precision on integers.
* Add wrapper for strncat
2020-06-22 00:14:37 +02:00
Patrick Pelissier d27c448a94 Fix some warnings with MSVS
for the test suite.
2020-06-21 23:52:12 +02:00
Patrick Pelissier 06a1590645 Add missing assertion. 2020-06-21 23:51:49 +02:00
Patrick Pelissier 652653af0b Fix some warnings by casting
for compilers which cannot detect the affectations as ok.
2020-06-21 23:50:49 +02:00
Patrick Pelissier c520b7d0be Enable Annex K for MSVS 2020-06-21 23:36:47 +02:00
Patrick Pelissier 4f4605befb Use of Annex K for MSVS to reduce warnings. 2020-06-21 23:36:34 +02:00
Patrick Pelissier 3f84f54d65 Add casts to avoid some compiler warnings
if the compiler is not able to detect the cast if safe.
2020-06-21 23:03:40 +02:00
Patrick Pelissier bf49b8e933 Enable warnings for MSVS 2020-06-21 22:43:06 +02:00
Patrick Pelissier 1edb204ec6 Update documentation 2020-06-19 21:14:46 +02:00
Patrick Pelissier dd5c9ac8ad Fix corner case of string_fget_word when it doesn't end with a separator 2020-06-19 21:11:05 +02:00
Patrick Pelissier 32b6f82249 Add corner case for string_fget_word when it doesn't end with a separator 2020-06-19 21:10:46 +02:00
Patrick Pelissier 44b3895698 Fix m_core_fscan_* in case of EOF 2020-06-19 21:02:17 +02:00
Patrick Pelissier 5ce6ccde3d Add bench for deque 2020-06-18 22:04:56 +02:00
Patrick Pelissier ee64e068f9 Add bench for rapidjson 2020-06-14 21:12:02 +02:00
Patrick Pelissier 8d89e7c958 Add leak sanitizer to sanitize target. 2020-06-14 11:33:01 +02:00
Patrick Pelissier ef74f8eb55 Fix other warnings about conversion but in C++ 2020-06-14 01:10:37 +02:00
Patrick Pelissier a7749e944f Fix strange warning with gcc 2020-06-14 00:48:58 +02:00
Patrick Pelissier 18bf06ff5f Add m_core_serial_fail for make debugging easier for serialization
Fix issue in saving size_t for 32 bits system
2020-06-14 00:40:11 +02:00
Patrick Pelissier b27f490acb Fix typing 2020-06-14 00:18:26 +02:00
Patrick Pelissier e84fa859c6 Fix implicit conversion. 2020-06-14 00:17:44 +02:00
Patrick Pelissier 4c57ca69bc Support for 32 bits system. 2020-06-14 00:17:22 +02:00
Patrick Pelissier b0d2557ea1 string_fgets:
Fix buffer overflow for very big string
2020-06-14 00:17:09 +02:00
Patrick Pelissier 82906e03e9 Add warning also for GCC. 2020-06-13 20:02:29 +02:00
Patrick Pelissier 1859868838 Fix sign conversion for algorithm tests. 2020-06-13 20:02:14 +02:00
Patrick Pelissier 4ab3a3605b Fix -Wsign-conversion warnings in tests. 2020-06-13 19:43:52 +02:00
Patrick Pelissier 279b46b4e2 Fix -Wsign-conversion warnings. 2020-06-13 19:43:38 +02:00
Patrick Pelissier 17950c5fe5 Fix corner cases for string_reserve 2020-06-13 18:57:53 +02:00
Patrick Pelissier 45b94c8abc Add corner cases for string_reserve 2020-06-13 18:57:39 +02:00
Patrick Pelissier a98ebd3b20 Fix test. 2020-06-13 18:53:40 +02:00
Patrick Pelissier cb7cd1ac67 Simplify code 2020-06-13 18:53:28 +02:00
Patrick Pelissier 9a41faf40a Fix -Wsign-conversion warning for strings. 2020-06-13 18:41:23 +02:00
Patrick Pelissier 8c44362f74 More test case. 2020-06-13 18:41:06 +02:00
Patrick Pelissier 548c0c0c61 Fix -Wsign-conversion warning 2020-06-13 18:37:10 +02:00
Patrick Pelissier 607221f480 Fix expected result due to change in list + INIT_WITH 2020-06-13 18:19:29 +02:00
Patrick Pelissier 160c76361b Add -Wsign-conversion when checking with clang 2020-06-13 18:15:53 +02:00
Patrick Pelissier 2fadad0c8d Fix warnings raised by -Wsign-conversion of clang
in m-core.h
2020-06-13 18:15:26 +02:00
Patrick Pelissier 4d4973abcc Fix warning 2020-06-13 17:57:31 +02:00
Patrick Pelissier f8ae9eb677 Add bench of serialization of integers 2020-06-13 17:38:14 +02:00
Patrick Pelissier de825203cf Ignore other temporary files 2020-06-13 17:37:54 +02:00
Patrick Pelissier 4f865176d3 Add bench for serialization. 2020-06-13 17:30:58 +02:00
Patrick Pelissier cb4b43e2e8 * Add length param for seralization write_string
to increase a little bit the performance for big strings.
* Change the format of storing strings for serial-bin.
2020-06-13 17:26:07 +02:00
Patrick Pelissier 89b6e1aac0 Adding serialization for bounded string 2020-06-13 11:30:52 +02:00
Patrick Pelissier daeaa242b8 Add new types to be used for M_LET:
* m_serial_bin_write_t
* m_serial_bin_read_t
2020-06-13 11:21:33 +02:00
Patrick Pelissier 100af17328 Make copyright notice explicit 2020-06-13 10:44:47 +02:00
Patrick Pelissier 7527bfec85 Update comments 2020-06-13 00:17:35 +02:00
Patrick Pelissier f73d25c92d Update documentation after renaming 2020-06-12 20:00:20 +02:00
Patrick Pelissier 9080f5d52f Add basic tests for M_KEEP_ARGS / M_SKIP_ARGS / M_MID_ARGS 2020-06-12 20:00:04 +02:00
Patrick Pelissier 6beb142bbe Fix conflict with SVID2/XPG mallopt options #53 2020-06-12 19:58:18 +02:00
PpHd 9b8b93288a Merge pull request #51 from vladipus/patch-1
Update README.md
2020-06-12 19:42:51 +02:00
Vladislav Dmitrievich Turbanov 6a2a549ec5 Update README.md
Fixed a M_IPTR missing *
2020-06-11 19:46:40 +03:00
Patrick Pelissier 468b7e7a0c Add bench for CMC 2020-06-10 22:29:59 +02:00
Patrick Pelissier fd640e9232 Update change of behaviors 2020-06-08 22:58:52 +02:00
Patrick Pelissier d13d7feae3 Update test as per new behavior 2020-06-08 22:58:41 +02:00
Patrick Pelissier 17f69326e2 Reverse order of a list initialized with M_LET to match the behavior of array 2020-06-08 22:58:30 +02:00
Patrick Pelissier 273fcd51b6 Add bench for rigtorp MPMCQueue 2020-06-06 12:00:52 +02:00
Patrick Pelissier f4b9185ceb Update documentation on QUEUE_MPMC 2020-06-06 11:09:55 +02:00
Patrick Pelissier b722227b39 Update comment 2020-06-05 21:06:06 +02:00
Patrick Pelissier 3d7e2f5c6b Fix m*lib version 2020-06-05 21:01:11 +02:00
Patrick Pelissier 9369530068 Comments & formating 2020-06-05 20:50:34 +02:00
Patrick Pelissier 4e968c3777 Comment the exponential backoff object. 2020-06-05 20:39:16 +02:00
Patrick Pelissier 9a5302ac19 Rename internal backoff
to avoid consummign too much namespace
2020-06-05 20:34:31 +02:00
Patrick Pelissier 8216ef0f7b Factorization of check of index
So that it can be reused for other modules.
2020-06-05 20:30:07 +02:00
Patrick Pelissier b897027021 Add user customizable ARRAY macro
for checking if index is within the allowedd bounds even in release mode
2020-06-05 00:11:22 +02:00
Patrick Pelissier 6095cf8610 Reindent file. 2020-06-04 23:51:17 +02:00
Patrick Pelissier e917ac5663 Update comments and simplify 2020-06-02 22:57:38 +02:00
Patrick Pelissier 2b44892aad Add more comments 2020-05-31 00:36:47 +02:00
Patrick Pelissier 294e45c7e1 Add comments 2020-05-31 00:15:46 +02:00
Patrick Pelissier 467acfdd10 Use of M_BOOL_OPLIST
to avoid warnings.
2020-05-30 23:45:46 +02:00
Patrick Pelissier d3823951b5 Add M_BOOL_OPLIST 2020-05-30 23:45:29 +02:00
Patrick Pelissier cc33079d43 Add comments 2020-05-30 23:38:31 +02:00
Patrick Pelissier 78d0bfb286 Port new error oplist format to all containers. 2020-05-30 18:00:43 +02:00
Patrick Pelissier b2f5ae6917 Proper generation. 2020-05-30 17:54:58 +02:00
Patrick Pelissier 9c723da768 Change format of errror on oplist
This is to enable M_GLOBAL_OPLIST_OR_DEF to properly expand the erroneous oplist to the backend generator, that will report the error.
As such the erreneous oplist is surrounded by two pairs of brackets (())
2020-05-30 17:54:22 +02:00
Patrick Pelissier 70c3932f6e Add new test on proper error checking 2020-05-30 17:52:31 +02:00
Patrick Pelissier 92bddcaab4 Fix preprocessing issue
in case of recursive tuple or variant.
2020-05-30 12:13:43 +02:00
Patrick Pelissier 79a8401d75 Fix oplist definiiton
Improve test suite
2020-05-30 12:07:21 +02:00
Patrick Pelissier 570473e465 Improve test suite. 2020-05-30 11:33:37 +02:00
Patrick Pelissier 990b7b02d7 Update list of expected failures 2020-05-30 11:23:53 +02:00
Patrick Pelissier 0b301d1cea Fix oplist definition. 2020-05-30 11:12:15 +02:00
Patrick Pelissier f35db79792 Work around C++ warnings 2020-05-30 10:46:17 +02:00
Patrick Pelissier dc1f163716 Fix option name with new cl 2020-05-30 10:41:51 +02:00
Patrick Pelissier 4d6bb407ee Reenable MSVC test suite with new compiler version (16.6) 2020-05-30 10:34:02 +02:00
Patrick Pelissier 37cef298c6 Update format 2020-05-29 21:49:03 +02:00
Patrick Pelissier 0396d1f648 Go to next development version 2020-05-29 21:07:43 +02:00
Patrick Pelissier e694d83cc4 V0.4.0 2020-05-27 21:50:03 +02:00
Patrick Pelissier 19fc150763 Discard warning with clang++ 2020-05-27 21:41:31 +02:00
Patrick Pelissier 3784f653d9 Fix warning with CLANG 2020-05-27 21:41:11 +02:00
Patrick Pelissier eb40cff6a1 Improve checkall target to stop on warning 2020-05-27 21:09:07 +02:00
Patrick Pelissier b7f84236d3 * Update comments
* Micro optimization
2020-05-25 21:41:16 +02:00
Patrick Pelissier 65e3f1049b * Update comments.
* Fix position of const for some prototypes.
2020-05-25 00:23:12 +02:00
Patrick Pelissier cc45b9c1fe Fix issue in test suite. 2020-05-24 20:39:20 +02:00
Patrick Pelissier 9340c2e55c Fix memory leak for _parse_str in case of error. 2020-05-24 19:50:32 +02:00
Patrick Pelissier 9710e014f2 Reindent function 2020-05-24 19:19:19 +02:00
Patrick Pelissier 7761fb6bf1 Add contract for tuple & variant. 2020-05-24 19:08:18 +02:00
Patrick Pelissier 2f4df5f67c Fix potential read before init in test. 2020-05-24 19:07:29 +02:00
Patrick Pelissier b841f81416 Fix package name for MS Windows
The filesystem doesn't support '*'
2020-05-24 18:14:25 +02:00
Patrick Pelissier 72fd53ab44 Update comments 2020-05-24 12:01:56 +02:00
Patrick Pelissier 8335bc525b Add comments 2020-05-23 16:09:18 +02:00
Patrick Pelissier 9e5d14ce36 Factorization & add tests 2020-05-21 13:10:50 +02:00
Patrick Pelissier 3bafede8b7 * Make the test more pertinent 2020-05-21 12:32:33 +02:00
Patrick Pelissier 3f2904ab0d * Add comment 2020-05-21 12:32:20 +02:00
Patrick Pelissier 933b495ed1 * Optimization for M_LET for a string_t in case of constant non formatted string
* Support for string_t in M_LET for string_t in C11 mode.
* Adding associate test
2020-05-21 12:19:17 +02:00
Patrick Pelissier 77813adc00 Add example of formatted C string for string in M_LET 2020-05-21 11:55:35 +02:00
Patrick Pelissier ce2adea6c0 Update documentation 2020-05-21 09:54:08 +02:00
Patrick Pelissier 3ecdfff8f0 Remove more cleanly generated configuration file. 2020-05-21 00:54:24 +02:00
Patrick Pelissier a103ceb850 Add new example of array of string. 2020-05-21 00:36:35 +02:00
Patrick Pelissier 9f24b89487 Add debug flag for example 2020-05-21 00:36:13 +02:00
Patrick Pelissier 8be06cadb3 Add comments on description. 2020-05-20 23:21:27 +02:00
Patrick Pelissier c488d979cf Ignore Visual Code directory if any. 2020-05-20 23:05:28 +02:00
Patrick Pelissier f4c24f07af Update comment description of macros and functions 2020-05-20 22:36:36 +02:00
Patrick Pelissier 3d2ce63d63 Fix performance issue in benchmarks 2020-05-19 23:21:00 +02:00
Patrick Pelissier 0ac2c62ffe Port to new API 2020-05-19 22:57:08 +02:00
Patrick Pelissier 6001781e68 Cleanup namespace, add comments, and remove dead code 2020-05-17 21:39:24 +02:00
Patrick Pelissier d90cb7caf3 Update doc 2020-05-17 12:11:10 +02:00
Patrick Pelissier 88a4835025 Fix issue when defining algorithm with same prefix than container 2020-05-17 12:11:04 +02:00
Patrick Pelissier 75ae7a06e5 Add missing tests 2020-05-17 11:53:43 +02:00
Patrick Pelissier 3885cb29a2 Add control of type and oplists 2020-05-17 11:53:27 +02:00
Patrick Pelissier bf3ffd1766 Add test cases for new control 2020-05-17 11:10:06 +02:00
Patrick Pelissier d884d257bb Export TYPE operator in oplist 2020-05-17 10:53:17 +02:00
Patrick Pelissier a87cac84dd Move up control so that it is the first error reported by the compiler. 2020-05-17 10:52:54 +02:00
Patrick Pelissier d1ae26f0fd * Add control than the type and the oplist are compatible 2020-05-17 10:27:30 +02:00
Patrick Pelissier 9c58e73c37 * Add M_CHECK_COMPATIBLE
* Fix issue in oplist
2020-05-17 10:26:40 +02:00
Patrick Pelissier 024b62a7a7 Add instance for M_CHECK_COMPATIBLE to be able to check multiple types within one container. 2020-05-17 10:26:08 +02:00
Patrick Pelissier c59731775e * Provide alternative for M_STATIC_ASSERT in GNUC + C11 with improved error messages
* Add internal macro M_CHECK_COMPATIBLE_OPLIST to check if a type and an oplist could match.
2020-05-17 09:36:50 +02:00
Patrick Pelissier 4668476c6a Fix issue with old version of ICC 2020-05-16 14:47:30 +02:00
Patrick Pelissier 743959ebde Fix micro performance issue 2020-05-16 14:09:49 +02:00
Patrick Pelissier dd27fa7e72 Add coverage for Function Object 2020-05-16 10:24:29 +02:00
Patrick Pelissier f2025f83d3 Fix help usage 2020-05-16 09:41:05 +02:00
Patrick Pelissier 8c06b43b2b Update tests for new controls 2020-05-15 21:46:18 +02:00
Patrick Pelissier 3cde7a1731 Add protection for use of oplist within a container oplist 2020-05-15 21:46:03 +02:00
Patrick Pelissier e9db1d28b8 Try to work around to print the oplist 2020-05-15 21:45:21 +02:00
Patrick Pelissier adffaf0e87 Fix illegal usage of oplist for function object 2020-05-15 21:45:02 +02:00
Patrick Pelissier 49a2e600c4 Add control of sub-oplist when creating a new oplist of a container
Add test case of this new control
Fix some corner bugs in some containers evolving their own oplists.
2020-05-15 21:19:39 +02:00
Patrick Pelissier 0bedcba32b Rewrite M_STATIC_ASSERT to include an error code and message
Add more control on the default expanded macros to check if arguments are compatible
2020-05-15 14:51:20 +02:00
Patrick Pelissier c531f805b0 Define _reduce only if SET method is properly set 2020-05-15 14:31:47 +02:00
Patrick Pelissier da0ab5ea98 Update failure tests as per latest checks 2020-05-11 20:55:16 +02:00
Patrick Pelissier 6774afd751 Add checks of missing oplist in the last _DEF macros 2020-05-11 20:54:50 +02:00
Patrick Pelissier 6d489136e7 Update help 2020-05-10 22:18:19 +02:00
Patrick Pelissier 4ea6dbc7fa Update makefile as per latest version of library 2020-05-10 20:21:03 +02:00
Patrick Pelissier defc58f6a3 Update bench code to latest version of the library. 2020-05-10 20:20:37 +02:00
Patrick Pelissier 006d0d16a5 Fix error 2020-05-10 20:20:03 +02:00
Patrick Pelissier b8af8bb344 Redisable MSVC testing with new version of compiler 2020-05-10 12:40:37 +02:00
Patrick Pelissier e249be1142 Reenable MSVC testing with new version of compiler 2020-05-10 12:38:36 +02:00
Patrick Pelissier 05fde6c3cf Display MSVC compiler full version 2020-05-10 12:06:31 +02:00
Patrick Pelissier aaa1d7dc4b Update description of test 2020-05-10 11:20:16 +02:00
Patrick Pelissier 8c479b2e5a Update tests 2020-05-10 11:17:25 +02:00
Patrick Pelissier 45d2a529b5 Add more validation of oplists before expanding data 2020-05-10 11:16:46 +02:00
Patrick Pelissier 7d17223332 Update comments 2020-05-10 11:15:56 +02:00
Patrick Pelissier 12bc65b6a8 Fix spelling 2020-05-10 11:15:28 +02:00
Patrick Pelissier a849d5c031 Make check-failure tests parallel 2020-05-09 21:39:01 +02:00
Patrick Pelissier f195b09657 Add more tests 2020-05-09 21:38:48 +02:00
Patrick Pelissier 439177ec71 Add protection against wrong oplist in more headers 2020-05-09 21:38:32 +02:00
Patrick Pelissier aadd4f11b1 Update tests as per new checks 2020-05-09 17:16:11 +02:00
Patrick Pelissier 113fdbf388 Add more controls on proper presence of oplist for _DEF macros 2020-05-09 17:16:00 +02:00
Patrick Pelissier 648406a99a Update tests as per new checks 2020-05-09 16:11:11 +02:00
Patrick Pelissier 055e74d350 Add more check for valid oplists before expanding further 2020-05-09 16:10:56 +02:00
Patrick Pelissier ac3d7568f2 Update test 2020-05-09 11:20:05 +02:00
Patrick Pelissier 6c222b9ad7 Raise proper failure if M_let is used without an oplist
Raise proper failure if a TYPE operator is used in an oplist that doesn't export it.
2020-05-09 11:15:44 +02:00
Patrick Pelissier 4426a60904 Add test for testing expected failures 2020-05-09 10:56:31 +02:00
Patrick Pelissier 34f70a031f Use M_STATIC_FAILURE to stop expanding methods in case of detected failure 2020-05-09 10:56:05 +02:00
Patrick Pelissier 79f2f396b9 Add macro M_STATIC_FAILURE to abort expansion in case of error 2020-05-09 10:55:25 +02:00
Patrick Pelissier 88143f7d52 Update ignore file 2020-05-09 10:54:30 +02:00
Patrick Pelissier c1261dd0f2 Fix doc 2020-05-08 21:47:19 +02:00
Patrick Pelissier 8f7a60ea73 Add documentation for function object 2020-05-08 21:43:35 +02:00
Patrick Pelissier 4758bbd6cc Add more tests 2020-05-08 21:23:48 +02:00
Patrick Pelissier 3f66325c19 Add new example for function object, json & algorithms 2020-05-08 17:50:07 +02:00
Patrick Pelissier 6f10d7deb9 Add synonym of serialisater with specialized oplists to be used in RAII 2020-05-08 17:49:44 +02:00
Patrick Pelissier 919900c90a Update documentation 2020-05-08 17:48:56 +02:00
Patrick Pelissier e6daaf429c Add some tests for function objects 2020-05-08 11:37:38 +02:00
Patrick Pelissier 1200f30695 * Add more Function Object support in algorithm
* Fix bug of selection sort
2020-05-08 11:35:22 +02:00
Patrick Pelissier fca1120990 No longer export IT_REF for map containers (See API changes) 2020-05-08 11:33:28 +02:00
Patrick Pelissier 3735704c95 Update new API change 2020-05-08 11:30:57 +02:00
Patrick Pelissier 8c0c1b3102 Update documentation of reduce if the container is empty 2020-05-08 11:30:38 +02:00
Patrick Pelissier db192993f1 Reduce constraint as the dictionnary iteration is not modifiable 2020-05-08 00:27:15 +02:00
Patrick Pelissier 4f44b3f60b Add CMP callback 2020-05-07 22:13:36 +02:00
Patrick Pelissier b196fcc3c0 Rename _cmp_cb_t into _eq_cb_t 2020-05-07 22:10:53 +02:00
Patrick Pelissier 395f1af19e Implement more function object algorithm 2020-05-07 22:09:07 +02:00
Patrick Pelissier d8f761e889 Update Makefile for dist 2020-05-05 23:44:27 +02:00
Patrick Pelissier 563ffb4275 Add first support for function object for certain algos (WIP) 2020-05-05 23:34:34 +02:00
Patrick Pelissier 9ba2de4b70 Add macro M_IF_FUNCOBJ to handle conditional expression if the function object is defined 2020-05-05 23:34:12 +02:00
Patrick Pelissier 0ac6a53fe9 Define callback types 2020-05-05 22:57:19 +02:00
Patrick Pelissier 4431e9f9ae Factorization / Split of the definition of the algorithm 2020-05-05 22:40:03 +02:00
Patrick Pelissier 48526ff5c7 Simplify logic due to fix of M_PARENTHESIS_P 2020-05-04 00:33:00 +02:00
Patrick Pelissier 4ee453025c Add comments 2020-05-04 00:32:40 +02:00
Patrick Pelissier 1e7b543c0f Fix issue with oplists with 3 arguments and fix warnings 2020-05-04 00:30:14 +02:00
Patrick Pelissier 8c2b4f8cf9 Add test cases for function object 2020-05-04 00:29:42 +02:00
Patrick Pelissier 13cadfa470 Update description of the list of headers 2020-05-03 18:00:46 +02:00
Patrick Pelissier deb595372b Add first version of Function Object 2020-05-03 17:49:02 +02:00
Patrick Pelissier 01fd5d929e * Fix M_RET_ARG so that it accepts also a list of the exact number of arguments (instead of one more) * Add more keywords for pattern recognation 2020-05-03 13:13:45 +02:00
Patrick Pelissier 2d60bd2c1b Fix a bug in M_PARENTHESIS_P 2020-05-02 10:19:31 +02:00
Patrick Pelissier 9655b13203 Add more corner cases for M_PARENTHESIS_P 2020-05-02 10:18:52 +02:00
Patrick Pelissier 6b97a7436d Add basic tests for dispathing init_with based on their number of args 2020-05-02 10:06:30 +02:00
Patrick Pelissier 1c792dd0a4 Add option for init_with to dispatch to different methods in function of the number of args 2020-05-02 10:06:08 +02:00
Patrick Pelissier dcbd9f496f Document NAME operator 2020-05-02 09:56:23 +02:00
Patrick Pelissier 9804120cde * Add simple test for registration of int global operator 2020-05-02 09:56:11 +02:00
Patrick Pelissier a9b06718f0 * Add simple test for NAME operator 2020-05-02 09:55:28 +02:00
Patrick Pelissier 963d819e22 * Add NAME operator. * Register default oplist for char,short,int,long,float,double 2020-05-02 09:55:10 +02:00
Patrick Pelissier 28847af43f Update constraints on MOVE & INIT_MOVE operators 2020-04-27 23:12:06 +02:00
Patrick Pelissier 130fa36970 Update iterator constraint 2020-04-27 22:55:53 +02:00
Patrick Pelissier ab99035291 Add another example 2020-04-20 23:50:05 +02:00
Patrick Pelissier 6de43d8a45 Add doc for ALGO_REDUCE with different type 2020-04-20 23:49:48 +02:00
Patrick Pelissier 7b46891622 Add test for ALGO_REDUCE with different type 2020-04-20 23:49:35 +02:00
Patrick Pelissier a0a32d8c6c ALGO_REDUCE accept dest with different type than the container 2020-04-20 23:49:16 +02:00
Patrick Pelissier 1ffd07dc6e Update format 2020-04-11 00:25:40 +02:00
Patrick Pelissier cb49cd7100 * Fix integer overflow in test of mul reduction 2020-04-10 08:35:44 +02:00
Patrick Pelissier 923b340a80 * Update documentation 2020-04-10 08:29:55 +02:00
Patrick Pelissier 5b8750ee2a * Add support for product in ALGO_REDUCE 2020-04-10 08:28:16 +02:00
Patrick Pelissier d438d089fb Add note on the provided oplists 2020-04-10 08:19:59 +02:00
Patrick Pelissier 843ddac3dd Proper prefix internal variables of macros by '_' 2020-04-01 23:40:41 +02:00
Patrick Pelissier c5238e0a4c Add new example for algorithm 2020-04-01 23:40:16 +02:00
Patrick Pelissier f99ee8aa40 Update documentation 2020-04-01 23:28:07 +02:00
Patrick Pelissier 18c7d0e11a Add test for SET_KEY only containers for ALGO_EXTRACT 2020-04-01 23:27:38 +02:00
Patrick Pelissier 4e67823593 Add support for SET_KEY only containers for ALGO_EXTRACT 2020-04-01 23:27:20 +02:00
Patrick Pelissier e7fcefb391 * Dict supports INIT_WITH method too. 2020-03-29 00:49:36 +01:00
Patrick Pelissier be06426783 Add documentation for ALGO_TRANSFORM 2020-03-28 17:41:29 +01:00
Patrick Pelissier e558e83be3 Add test case for ALGO_TRANSFORM 2020-03-28 17:41:16 +01:00
Patrick Pelissier d77a235b2a Add macro ALGO_TRANSFORM 2020-03-28 17:41:04 +01:00
Patrick Pelissier 3add6bb5bf Improve test suite 2020-03-28 17:17:43 +01:00
Patrick Pelissier 4367daaa00 Add documentation for _transform method. 2020-03-28 13:34:17 +01:00
Patrick Pelissier 4d46b3d126 Add basic test cases for _transform method. 2020-03-28 13:34:02 +01:00
Patrick Pelissier 548cd84a7f Add _transform method for algorithm. 2020-03-28 13:33:43 +01:00
Patrick Pelissier d87ffaa572 Improve documentation. 2020-03-28 13:07:35 +01:00
Patrick Pelissier 370cdb4e45 Add another example. 2020-03-28 13:05:15 +01:00
Patrick Pelissier 068d023917 Factorize in m-core.h the pattern recognication. 2020-03-28 11:36:51 +01:00
Patrick Pelissier 86b6ad54d5 Rename filln, filla, fillan into fill_n, fill_a, fill_an (same name as C++) 2020-03-28 11:10:02 +01:00
Patrick Pelissier bdf999a9fc Disable fully VC++ build as the build is fully broken due to regression in version 16.5 vs 16.4 2020-03-26 22:34:51 +01:00
Patrick Pelissier 39f8b6828b Try workaround against regression with new VisualC++ 2020-03-26 22:03:11 +01:00
Patrick Pelissier 11f84ab34b Document new algorithms 2020-03-26 21:49:04 +01:00
Patrick Pelissier c3a5306266 Add function _fill, _filln, _filla, _fillan as algorithms 2020-03-26 21:48:46 +01:00
Patrick Pelissier 1fe9e4c14c Export ADD / MUL / DIV / SUB for basic C types. 2020-03-26 21:44:19 +01:00
Patrick Pelissier e69203dc50 Remove exported PUSH / POP methods as they don't follow stricly the prototypes of such functions. 2020-03-26 21:43:44 +01:00
Patrick Pelissier 342954f272 Fix introduced build error for Mingw 2020-03-25 11:56:38 +01:00
Patrick Pelissier 741d6b8828 Test string + algorithm 2020-03-25 11:44:35 +01:00
Patrick Pelissier f1f41ef320 * Add missing iterator functions * Export iterators in oplist so that it is usable in algorithm 2020-03-25 11:43:55 +01:00
Patrick Pelissier 785792d1f4 Allow build of examples in C11 mode 2020-03-25 11:17:06 +01:00
Patrick Pelissier 9affe3106c Add example of ALGO_FOR_EACH and ALGO_REDUCE 2020-03-25 11:16:19 +01:00
Patrick Pelissier eb9fd14e2c Fix documentation. 2020-03-25 10:19:43 +01:00
Patrick Pelissier c281a2c339 Update CI script to include VC++ 2020-03-02 18:09:53 +01:00
Patrick Pelissier cb109eb479 Add proper progression for special script 2020-03-02 14:35:49 +01:00
Patrick Pelissier 3c6d194974 Add script to launch the test suite with VC++ 2020-03-02 14:25:42 +01:00
Patrick Pelissier 653a0d9734 Fix build issue for systems where double==long double 2020-03-02 14:23:59 +01:00
Patrick Pelissier a5fbd8405c Avoid C99 construct incompatible with strict C++ compiler 2020-02-24 22:27:43 +01:00
Patrick Pelissier 70994d4f60 Update doc 2020-02-16 11:06:43 +01:00
Patrick Pelissier f15203afb2 Comment a little bit more the examples 2020-02-10 06:47:24 +01:00
Patrick Pelissier 0a0d707afd Document bitset 2020-02-08 23:39:30 +01:00
Patrick Pelissier e206c3fe48 Document SPSC buffer 2020-01-23 23:18:33 +01:00
Patrick Pelissier 7f5704d321 Document MPMC buffer 2020-01-09 22:52:02 +01:00
Patrick Pelissier 4f7b0b9455 Happy new year 2020 2020-01-04 15:41:06 +01:00
Patrick Pelissier f5f16015df In quiet mode, if the result of the bench is not assumed to be reliable, display -1 instead of the result. 2020-01-04 15:12:59 +01:00
Patrick Pelissier 935325e0cb Add bench of emilib 2020-01-04 15:06:24 +01:00
Patrick Pelissier 7b9530ac58 Fix name of bench 2020-01-04 15:05:12 +01:00
Patrick Pelissier a9fc259420 ALGO_EXTRACT func argument is now optional 2019-12-30 14:31:21 +01:00
Patrick Pelissier 6f603b52df Update comments 2019-12-30 14:11:41 +01:00
Patrick Pelissier aeb2a47952 Add comments to example 2019-12-30 13:44:03 +01:00
Patrick Pelissier ca7cea3fe3 Use of linear probing and the same hash function as other libraries 2019-12-30 00:12:05 +01:00
Patrick Pelissier f14aca8808 Port to new UDB2 protocol 2019-12-29 23:51:30 +01:00
Patrick Pelissier f1e5e9d9db Simplify code to use get_at method with its get & create semantic 2019-12-29 23:45:17 +01:00
Patrick Pelissier cecba9777a Update documentation on buffer/queues 2019-12-27 16:42:54 +01:00
Patrick Pelissier 4352267034 Update deprecated API 2019-12-27 16:42:00 +01:00
Patrick Pelissier 0c3730d9a3 Migrate version to 0.3.1 2019-12-27 16:41:42 +01:00
Patrick Pelissier 5111b0c726 Deprecated some buffer options since the _blocking functions are much more usefull 2019-12-27 16:39:42 +01:00
Patrick Pelissier 8ecd3f1592 Add best_within and variance 2019-12-23 23:05:48 +01:00
Patrick Pelissier 0a6f8851c9 Update list of bench to launch automatically 2019-12-20 21:37:51 +01:00
Patrick Pelissier f0d3e93d9d Tune for Windows CI: C11 is broken, so switch to C99 and requests ISO C compatible printf function. 2019-12-16 12:44:56 +01:00
Patrick Pelissier e77ff2451b Try setup CCI for windows 2019-12-16 12:31:10 +01:00
Patrick Pelissier 142c224f84 Add another example on complex structure usage 2019-12-15 19:53:46 +01:00
Patrick Pelissier 29e8d9199d Update doc about new API 2019-12-15 19:43:38 +01:00
Patrick Pelissier 7128f5add2 * Add support for API_6 & API_7. * Fix issue for DO_INIT_MOVE that doesn't support API calls 2019-12-15 19:43:26 +01:00
Patrick Pelissier 1b7bcda4e1 Add quiet mode. Add usage 2019-12-15 10:30:40 +01:00
Patrick Pelissier 03b6146ef0 Add option to print only the best or only the average 2019-12-15 10:12:38 +01:00
Patrick Pelissier e99735d2b6 Add repeat option for bench 2019-12-15 10:01:32 +01:00
Patrick Pelissier 7263629c55 Add rigtop hashmap 2019-12-14 20:59:01 +01:00
Patrick Pelissier 605ce9b938 * Update version * Update comments * Improve robustness 2019-12-14 11:12:59 +01:00
Patrick Pelissier 049d8b6ca6 Port to new libdynamic API 2019-12-13 23:00:57 +01:00
Patrick Pelissier 90d3dda830 Clean up generated plot files too 2019-12-09 07:53:43 +01:00
Patrick Pelissier 2022a66db3 * Update makefile (missing coverage) * Refactor 2019-12-08 22:17:56 +01:00
Patrick Pelissier 78c786070e Add coverage support 2019-12-08 22:17:27 +01:00
Patrick Pelissier c5c72007af Update list of files to distribute 2019-12-08 21:53:20 +01:00
Patrick Pelissier c60d59cb7a Port all benchs to new infrastructure 2019-12-07 19:21:21 +01:00
Patrick Pelissier 00111e3e3c Port more bench to new infrzastructure 2019-12-07 14:45:06 +01:00
Patrick Pelissier 5cc2ac17d9 Add support for generating gnuplot graph 2019-12-07 12:22:33 +01:00
Patrick Pelissier d37ea84ab5 Cleanup redundant 'time' word 2019-12-07 11:59:23 +01:00
Patrick Pelissier 5e335bc8bd * Port to generic parser 2019-12-07 11:58:47 +01:00
Patrick Pelissier 65765763ae * Add generic parser for bench. * Factorization 2019-12-07 11:58:19 +01:00
Patrick Pelissier 90f248fbe8 Rename interface field of serial object into m_interface (WINDOWS compatibility as it defines a macro called interface) 2019-12-06 21:13:37 +01:00
Patrick Pelissier a39cf23697 Remove a warning (WINDOWS) 2019-12-06 21:10:00 +01:00
Patrick Pelissier 261776762c Update debugging documentation 2019-12-02 23:38:29 +01:00
Patrick Pelissier f207f9441c Remove linker warning for examples 2019-11-30 00:33:53 +01:00
Patrick Pelissier ffed880e0a Fix static assert for C++ (disable them totally as static_assert doesn't work -- It can't be used in expressions) 2019-11-30 00:08:59 +01:00
Patrick Pelissier a79b67cea2 Generate better error message in case of missing methods in OPLIST for GCC/CLANG 2019-11-29 23:45:48 +01:00
Patrick Pelissier bc3c8b5bcd Fix M_DO_INIT_MOVE / M_DO_MOVE to be more conservative. M_MOVE_DEFAULT doesn't work for all types ([1] structure). A MOVE operator should be defined however. 2019-11-29 23:23:27 +01:00
Patrick Pelissier 3489bb42bc Add static assertion and use it for move/copy/cmp default 2019-11-29 23:13:28 +01:00
Patrick Pelissier 7fe36f7bd7 Add test for M_MOVE_DEFAULT 2019-11-29 23:12:34 +01:00
Patrick Pelissier 82fd4c94db Update CI (Simplify CI tests) 2019-11-25 23:09:54 +01:00
Patrick Pelissier 4fc48b490e Update CI 2019-11-25 23:05:25 +01:00
Patrick Pelissier 750e5e6d95 Add target checkall at root Makefile 2019-11-25 22:50:50 +01:00
Patrick Pelissier cb564128e6 Update doc 2019-11-24 09:16:43 +01:00
PpHd 047fc986f2 Setup github workflows for Continuous Integration 2019-11-24 09:05:44 +01:00
Patrick Pelissier aca800ef8a Fix warning with lastest GCC about strict overflow 2019-11-24 08:50:55 +01:00
Patrick Pelissier dde090d4b0 Make GMP optional for the examples 2019-11-24 08:34:39 +01:00
Patrick Pelissier 87183573ce Ignore generated configuration 2019-11-24 08:27:40 +01:00
Patrick Pelissier baddcc3855 Avoid warning about variable being unused (C11) 2019-11-23 23:28:36 +01:00
Patrick Pelissier ba531774a0 Fix doc 2019-11-21 06:28:28 +01:00
Patrick Pelissier 708d17a4d2 Update README on details on OPLIST 2019-11-21 06:27:32 +01:00
Patrick Pelissier 7d802c03e5 Update README on details on OPLIST 2019-11-21 06:26:10 +01:00
Patrick Pelissier 787e1e9965 Merge branch 'master' of https://github.com/P-p-H-d/mlib 2019-11-05 19:56:09 +01:00
Patrick Pelissier 625691d279 Clarify doc on m-worker 2019-11-05 08:13:16 +01:00
Patrick Pelissier 4f0148dc77 Update doc with new container 2019-11-02 12:56:00 +01:00
Patrick Pelissier c78f2b992f Add support for set based on OA hashmap (DICT_OASET_DEF) 2019-11-02 08:40:24 +01:00
Patrick Pelissier 9857db0d15 Prepare integration of set based on OA hashmap for _ref and _cref 2019-11-02 08:29:44 +01:00
Patrick Pelissier 8b71064643 Simplify code for SET (since EQUAL returns TRUE as an EMPTY method) 2019-11-02 08:24:42 +01:00
Patrick Pelissier bc39034f6d Prepare integration of set based on OA hashmap 2019-11-02 08:17:44 +01:00
Patrick Pelissier e6a9b8fc8e Add M_EMPTY_OPLIST 2019-11-02 08:16:45 +01:00
Patrick Pelissier 3db43dc2db Update comments 2019-11-02 07:33:48 +01:00
Patrick Pelissier d384d5ad6c Always use INIT_MOVE when shrinking or enlarging the OA hashmap (Reversing the order of the last scanning) 2019-11-01 20:01:02 +01:00
Patrick Pelissier 7b2004caad Remove item 2019-10-29 12:32:51 +01:00
Patrick Pelissier 6754f88861 Update 2019-10-29 12:32:36 +01:00
Patrick Pelissier 9393809dfd Update todo 2019-10-26 19:22:33 +02:00
Patrick Pelissier 79ecacb6c0 Clarify what dict to use 2019-10-26 11:11:37 +02:00
Patrick Pelissier 853acbad4b Update doc 2019-10-21 23:13:37 +02:00
Patrick Pelissier e158eac10a Update doc 2019-10-21 22:56:28 +02:00
Patrick Pelissier 48ca2a2384 Add bench for OA for big objects (it confirms that OA dict is not suited for such object) 2019-10-21 22:56:15 +02:00
Patrick Pelissier d9d3d3cbe3 Update doc 2019-10-16 07:03:43 +02:00
Patrick Pelissier 6b4f10bf45 Prepare common macros for both hash tables 2019-10-15 07:33:31 +02:00
Patrick Pelissier 3b647b982f Add linear bench 2019-10-14 21:29:27 +02:00
Patrick Pelissier 00b875ea53 Add linear hash map bench 2019-10-14 20:57:29 +02:00
Patrick Pelissier 545fc4d93c Update doc 2019-10-11 07:50:26 +02:00
Patrick Pelissier c41342739a Reformulate 2019-10-02 08:12:09 +02:00
Patrick Pelissier ed99c5aaa3 Fix spelling 2019-09-28 17:17:14 +02:00
PpHd 08842811e8 Merge pull request #48 from taboege/string-clear-get-str-stack
Fix string_clear_get_str when stack allocated
2019-09-26 07:19:14 +02:00
Tobias Boege 3ea063d1e0 Fix string_clear_get_str when stack allocated
If a string_t is stack-allocated, string_clear_get_str would still try
to copy it from the NULL heap pointer, resulting in a failed assertion.
Copy from the stack instead. Also add a test for this.
2019-09-26 05:39:49 +02:00
Patrick Pelissier a905f12915 Document _cmp_order for tuple 2019-09-22 08:06:56 +02:00
Patrick Pelissier 5d8548b92b Update 2019-09-04 07:41:46 +02:00
Patrick Pelissier 99b63e9c77 Update 2019-08-26 08:04:06 +02:00
Patrick Pelissier 4002ef5aff Fix spelling 2019-08-23 06:42:47 +02:00
Patrick Pelissier d31ccfe8a4 Simplify example code 2019-08-11 10:43:35 +02:00
Patrick Pelissier c4ab76a330 More examples 2019-08-09 08:14:12 +02:00
Patrick Pelissier 84d4277be3 Add new example with basic types usage 2019-08-08 22:23:06 +02:00
Patrick Pelissier 0a99814ce2 Fix comments 2019-08-06 20:47:24 +02:00
Patrick Pelissier 11d695cb57 Update doc 2019-07-31 07:45:31 +02:00
Patrick Pelissier 13e2d6b473 Update issues 2019-07-25 07:10:45 +02:00
Patrick Pelissier e8137e4218 Fix spelling 2019-07-24 21:27:06 +02:00
Patrick Pelissier fe5df08d6e Update comments 2019-07-20 09:32:09 +02:00
Patrick Pelissier f77017f35f Update current limitation 2019-07-16 23:21:52 +02:00
Patrick Pelissier ce93c00a7b Workaround limitation of M_MOVE_DEFAULT for [1] structure (==> It supposes now that the destination parameter is **not** a type with [1] tricks or at least not a pointer to it, instead of having this constraint for both arguments). 2019-07-16 23:21:41 +02:00
Patrick Pelissier b8f44cc219 Fix bug (number of reader was too big, resulting in potential segfault) 2019-07-16 23:00:10 +02:00
Patrick Pelissier 2c921fdefe Improve test suite of snapshot to detect incorrect issues of INIT/CLEAR call by a container. 2019-07-16 23:00:10 +02:00
Patrick Pelissier 20eb95ba45 Update comments 2019-07-16 23:00:10 +02:00
Patrick Pelissier 7a6239912e Simplify code 2019-07-12 12:30:04 +02:00
Patrick Pelissier 9067311788 Update comment 2019-07-12 11:50:46 +02:00
Patrick Pelissier 23b2e07132 Add basic testing for _push_move method 2019-07-11 13:38:58 +02:00
Patrick Pelissier c8f2c0e06e Add _push_move method for SPSC 2019-07-11 13:38:40 +02:00
Patrick Pelissier 72c4eb80a2 Add doc on non documented operators 2019-07-11 12:56:00 +02:00
Patrick Pelissier 1f18e788e6 Update comments 2019-07-11 12:36:01 +02:00
Patrick Pelissier f855e24b56 Add description of operator INC_ALLOC 2019-07-11 12:29:00 +02:00
Patrick Pelissier 84d1b7ad50 Update doc 2019-07-08 21:35:59 +02:00
Patrick Pelissier 9f82649aa8 Add test for multiset 2019-07-08 21:25:19 +02:00
Patrick Pelissier 791f586c7e Add back contract support for multimap / multiset 2019-07-08 21:18:59 +02:00
Patrick Pelissier 8d3b0cc94b Prepare support in contract for multimap/multiset 2019-07-08 21:14:15 +02:00
Patrick Pelissier 70d1dfeb8b Add test case for multimap 2019-07-08 16:23:59 +02:00
Patrick Pelissier 9a4c6ba0d5 WIP for multimap / multiset. 2019-07-08 16:23:45 +02:00
Patrick Pelissier ef2dbf89ee Improve test 2019-07-08 11:36:09 +02:00
Patrick Pelissier d30b776fb0 Add more test 2019-07-08 11:33:42 +02:00
Patrick Pelissier 6408b28513 Update comments, function name and prepare for multimap / multiset 2019-07-08 11:17:08 +02:00
Patrick Pelissier 32b3e21564 Start supporting multimap/multiet 2019-07-07 21:18:34 +02:00
Patrick Pelissier 1ef28bedcb Rename internal functions for clarity 2019-07-07 21:16:04 +02:00
Patrick Pelissier 1356bb746e Add more tests 2019-07-06 10:44:49 +02:00
Patrick Pelissier 23240a44d5 Change how the keys are split. Before key[i] ==> node[i] has all keys < key[i], node[i+1] has all keys >= key[i]. After key[i] ==> node[i] has all keys <= key[i], node[i+1} has all keys > key[i]. 2019-07-06 00:03:26 +02:00
Patrick Pelissier 589c023622 Update test 2019-07-06 00:01:13 +02:00
Patrick Pelissier 047b6c5a58 Update 2019-07-04 21:10:38 +02:00
Patrick Pelissier 951425e963 Update comments 2019-07-04 10:42:24 +02:00
Patrick Pelissier e69cbfcab3 Add parameter isMulti 2019-07-04 09:53:58 +02:00
Patrick Pelissier 37f3cd6a72 Rename method _it_to_p into _it_until_p. Add method _it_while_p 2019-07-03 18:57:24 +02:00
Patrick Pelissier ec7b5dd120 Remove deprecated methods 2019-07-03 18:06:52 +02:00
Patrick Pelissier d50a78171f Bump to version 0.3.0 2019-07-03 18:06:39 +02:00
Patrick Pelissier b422aec2cd Add new example 2019-06-25 07:04:33 +02:00
Patrick Pelissier 7ba0e03b4f Add comments 2019-06-20 21:36:12 +02:00
Patrick Pelissier c535766c22 Update/Clean up basic type 2019-06-17 07:26:11 +02:00
Patrick Pelissier 289a3fdc71 Fix confusing position of { 2019-06-10 23:20:36 +02:00
Patrick Pelissier 7f0b6208a4 Propose a shorter version of the example. 2019-06-10 22:59:47 +02:00
Patrick Pelissier 60a10eb799 Uniformize the macro names 2019-06-09 12:02:38 +02:00
Patrick Pelissier 5321085856 Uniformize & add intermediary evaluation step for dict oplist
(like all other containers)
2019-06-09 11:39:15 +02:00
Patrick Pelissier 03be814a4d Uniformize macro names 2019-06-09 11:38:39 +02:00
Patrick Pelissier 6c3f7683a5 Uniformize API 2019-06-09 11:26:45 +02:00
Patrick Pelissier 06d6a90a21 Uniformize internal macros 2019-06-09 11:02:45 +02:00
Patrick Pelissier 747da27489 Uniformize 2019-06-09 10:49:18 +02:00
Patrick Pelissier 2869345920 Add test dor dual-push list for algo 2019-06-09 10:05:34 +02:00
Patrick Pelissier 6b8938cf76 Update comments.
Rename / Uniformize internal macros.
2019-06-09 10:01:50 +02:00
Patrick Pelissier 8e7eae5751 Update comments. 2019-06-09 09:32:35 +02:00
Patrick Pelissier 1882148a7c Add more assertions 2019-06-08 10:45:24 +02:00
Patrick Pelissier e46746ce01 Fix format string 2019-06-08 10:33:26 +02:00
Patrick Pelissier 32917e2cfa Add variant & prioqueue to tests then with concurrent 2019-06-08 10:07:03 +02:00
Patrick Pelissier 65a243fc13 Add missing const 2019-06-08 10:06:47 +02:00
Patrick Pelissier 1e011cb851 Add missing const in prototypes. 2019-06-08 09:59:16 +02:00
Patrick Pelissier 48f585a4ee Update comments 2019-06-08 09:47:49 +02:00
Patrick Pelissier bc10b616ae Update doc 2019-06-08 09:31:18 +02:00
Patrick Pelissier 851f08131d Update 2019-06-07 07:46:54 +02:00
Patrick Pelissier e294f4557e Update 2019-06-06 22:07:09 +02:00
Patrick Pelissier 9e5775fc16 Add example of serialization 2019-06-06 07:44:33 +02:00
Patrick Pelissier 8eb95d0cdc Update doc 2019-06-05 22:05:02 +02:00
Patrick Pelissier 42f807d64b Rename test file 2019-06-02 10:39:55 +02:00
Patrick Pelissier d1bb97ac52 Add new serializer 2019-06-02 10:39:24 +02:00
Patrick Pelissier f502b16b1d Fix bug 2019-06-02 10:31:25 +02:00
Patrick Pelissier 51e5764258 Add comment 2019-06-02 10:05:27 +02:00
Patrick Pelissier ec2281c29a Use of proper cast 2019-06-02 09:25:19 +02:00
Patrick Pelissier acfe1cb7e8 Update documentation for serialization 2019-05-28 22:50:16 +02:00
Patrick Pelissier 594aebd903 Fix comment 2019-05-28 22:50:06 +02:00
Patrick Pelissier 8bca63ac08 Fix MD syntax 2019-05-28 21:54:12 +02:00
Patrick Pelissier c02ec4f94c Update comments 2019-05-19 10:27:23 +02:00
Patrick Pelissier 797ac1f0da Fix for 32 bits system 2019-05-18 18:55:51 +02:00
Patrick Pelissier 058d3202ff Amend 2019-05-18 14:09:10 +02:00
Patrick Pelissier 62fcdac9cb Update list of headers 2019-05-18 14:08:17 +02:00
Patrick Pelissier b9131353b6 Add test 2019-05-18 11:17:15 +02:00
Patrick Pelissier a34deb2f3b Workaround warning. 2019-05-18 11:17:15 +02:00
Patrick Pelissier 9ef4b5c93f Fix cast 2019-05-18 11:17:14 +02:00
Patrick Pelissier 417b0295be Add C++ compatibility 2019-05-18 11:17:14 +02:00
Patrick Pelissier d11409bcc6 Add proper cast 2019-05-18 11:17:14 +02:00
Patrick Pelissier 928b81f454 Fix return value for in_serial/out_serial 2019-05-18 11:17:14 +02:00
Patrick Pelissier 05a68157bc Add local argument to serial interface to enable serial interface to create local parameters if needed (for example for serial binary) 2019-05-18 11:17:14 +02:00
Patrick Pelissier b6d5b5462b Update interface needed for serial 2019-05-18 11:17:14 +02:00
Patrick Pelissier 1c77082a29 Update comments 2019-05-18 11:17:14 +02:00
Patrick Pelissier 363c55668d Add in_serial / out_serial methods for several containers 2019-05-18 11:17:14 +02:00
Patrick Pelissier 7ed85fb97a Add in_serial / out_serial for concurrent containers 2019-05-18 11:17:14 +02:00
Patrick Pelissier 585ea1293d Add in_serial / out_serial for lists 2019-05-18 11:17:14 +02:00
Patrick Pelissier 448072555f Update comments 2019-05-18 11:17:14 +02:00
Patrick Pelissier 4701d5919b Fix serial import/export for variant 2019-05-18 11:17:14 +02:00
Patrick Pelissier 0997f59665 Update for variant 2019-05-18 11:17:14 +02:00
Patrick Pelissier dcf7a94728 Add in_serial / out_serial for variant 2019-05-18 11:17:14 +02:00
Patrick Pelissier 12ba563416 Add assertions 2019-05-18 11:17:14 +02:00
Patrick Pelissier f2fffb9219 Factor comment 2019-05-18 11:17:14 +02:00
Patrick Pelissier 3f03615ed2 Simplify code by factoring fscanf calls 2019-05-18 11:17:14 +02:00
Patrick Pelissier bc6bda057c Add in_serial / out_serial for array 2019-05-18 11:17:14 +02:00
Patrick Pelissier aeebe42bfb Fix issues for EOF & parsing arrays 2019-05-18 11:17:14 +02:00
Patrick Pelissier 5c4c93b62f Add missing export/import JSON interface 2019-05-18 11:17:14 +02:00
Patrick Pelissier c3ddd48d38 Simplify code 2019-05-18 11:17:14 +02:00
Patrick Pelissier 98f3c40ac5 add export/import of JSON string 2019-05-18 11:17:14 +02:00
Patrick Pelissier ada1b9861f Add size_of_type field for reading too 2019-05-18 11:17:13 +02:00
Patrick Pelissier 50cc8689bb Add serial methods for string_t 2019-05-18 11:17:13 +02:00
Patrick Pelissier 83da861a9c Simplify code by using more fscanf possibility 2019-05-18 11:17:13 +02:00
Patrick Pelissier 1cb1d16e77 Simplify code by using fscanf behvior on white space 2019-05-18 11:17:13 +02:00
Patrick Pelissier b525723084 Implement Serial Json Read tuple 2019-05-18 11:17:13 +02:00
Patrick Pelissier 4accdc994d Add JSON/read interface 2019-05-18 11:17:13 +02:00
Patrick Pelissier ad9bee0eec Add JSON serializer 2019-05-18 11:17:13 +02:00
Patrick Pelissier 6c7ff1c723 Update/fix bugs 2019-05-18 11:17:13 +02:00
Patrick Pelissier 3b2aad1b2e Export new methods for tuple 2019-05-18 11:17:13 +02:00
Patrick Pelissier 5222fabf02 Add tuple support for serial 2019-05-18 11:17:13 +02:00
Patrick Pelissier 44abead174 Update IN_SERIAL & OUT_SERIAL for default types. 2019-05-18 11:17:13 +02:00
Patrick Pelissier 492d5f0f9a Add IN_SERIAL & OUT_SERIAL for default types. 2019-05-18 11:17:13 +02:00
Patrick Pelissier 9bc5ac3df8 Start implementating generic serialization 2019-05-18 11:17:13 +02:00
Patrick Pelissier 5c726d63f4 Fix 2019-05-15 07:38:16 +02:00
Patrick Pelissier 2cd0a8db74 Uniformize the way of displaying the location of errors in the error message 2019-05-11 01:16:54 +02:00
Patrick Pelissier 0fa0445fa9 Fix C++ warning -Wclass-memaccess with G++ >= 8 2019-05-10 23:13:54 +02:00
Patrick Pelissier 1e171f9cc0 Increase NARGS support to 75 2019-05-10 21:39:18 +02:00
Patrick Pelissier 8d16ea4bf4 Increase maximum number of operators per oplist to 75 2019-05-10 21:26:18 +02:00
Patrick Pelissier a0c2ead91d Fix bug for M_AS_TYPE and small types 2019-05-10 10:20:38 +02:00
Patrick Pelissier b2875f6ba0 Add BSTRLIB for MASTER STRING BENCHMARK 2019-05-10 08:18:38 +02:00
Patrick Pelissier edb4ccf63e Add algo functions _remove_val & _remove_if 2019-05-07 16:35:39 +02:00
Patrick Pelissier 481009d18b Add function _end_with for strings. 2019-05-07 16:12:43 +02:00
Patrick Pelissier 6153383dab Update indent 2019-05-07 16:05:47 +02:00
Patrick Pelissier 74fed41818 Update version 2019-05-07 16:01:50 +02:00
Patrick Pelissier 2d5de1b9ea Update comments 2019-04-29 12:32:29 +02:00
Patrick Pelissier e23691c743 Fix spelling 2019-04-24 07:47:15 +02:00
Patrick Pelissier aaac236db6 Update README 2019-04-22 18:31:47 +02:00
Patrick Pelissier ccccedc2d5 Rework failure messages. 2019-04-22 18:30:46 +02:00
Patrick Pelissier 446afb04c7 Remove unused macro M_INIT_FAILURE 2019-04-22 12:07:53 +02:00
Patrick Pelissier 87cd964329 Uniformize error messages 2019-04-22 11:45:29 +02:00
Patrick Pelissier 80a344e46d Update version 2019-04-22 11:34:35 +02:00
Patrick Pelissier f2eb5014ac Fix regression on 32 bits for strings. 2019-04-21 23:50:42 +02:00
Patrick Pelissier d6c72061ce add new bench on strings 2019-04-21 23:13:29 +02:00
Patrick Pelissier 7c26fd25c9 Add SDS & RAPIDSTRING replace function implemented at used level 2019-04-21 19:54:20 +02:00
Patrick Pelissier 10e12d2b5c Update 2019-04-21 11:21:45 +02:00
Patrick Pelissier b9070f89d9 Update 2019-04-21 10:43:17 +02:00
Patrick Pelissier 46d41a8882 Fix bad merge 2019-04-20 12:33:09 +02:00
Patrick Pelissier b5dc3481d4 Update doc 2019-04-20 12:33:08 +02:00
Patrick Pelissier c18cd81dde Add more assumes needed for static analysis. 2019-04-20 12:33:08 +02:00
Patrick Pelissier eaf5a26157 Minor speed up 2019-04-20 12:33:08 +02:00
Patrick Pelissier 547c67b676 Modify string_t so that it can still be trivially movable once again. 2019-04-20 12:33:08 +02:00
Patrick Pelissier c89d6ef0ce Fix test. 2019-04-20 12:33:08 +02:00
Patrick Pelissier a54041c340 Minor fix 2019-04-20 12:33:08 +02:00
Patrick Pelissier 352e0972cd Comment code 2019-04-20 12:33:08 +02:00
Patrick Pelissier 91ebd7cc9f Cleanup code 2019-04-20 12:33:08 +02:00
Patrick Pelissier d8854c276b Cleanup code 2019-04-20 12:33:08 +02:00
Patrick Pelissier cc61840ae8 Refactor code 2019-04-20 12:33:08 +02:00
Patrick Pelissier 67a7a4762a Refactor code 2019-04-20 12:33:08 +02:00
Patrick Pelissier c28597014f Add more hypothesis 2019-04-20 12:33:08 +02:00
Patrick Pelissier d00f29bf26 Fix bug 2019-04-20 12:33:08 +02:00
Patrick Pelissier 1432fbabca Update buffer to have proper alignement so that we can perform hash computation properly. 2019-04-20 12:33:08 +02:00
Patrick Pelissier f3b6ee0190 Continue porting to new format. 2019-04-20 12:33:08 +02:00
Patrick Pelissier 229d21ef72 Add assume 2019-04-20 12:33:08 +02:00
Patrick Pelissier 00f1b1fc4f Update comment 2019-04-20 12:33:08 +02:00
Patrick Pelissier 277d8b37af Continue porting to new format. 2019-04-20 12:33:08 +02:00
Patrick Pelissier 7b83761ef4 Update 2019-04-20 12:33:08 +02:00
Patrick Pelissier a96e9c7e11 Update string contract 2019-04-20 12:33:08 +02:00
Patrick Pelissier 866721d067 Add first prototype of string with stack allocation. 2019-04-20 12:33:08 +02:00
Patrick Pelissier b356c29c89 Add PGO 2019-04-20 12:29:59 +02:00
Patrick Pelissier a2f7cb7670 Add C Macro Collections ref 2019-04-20 10:24:20 +02:00
Patrick Pelissier 08887c1df0 Add PGO 2019-04-20 09:08:10 +02:00
Patrick Pelissier 8b0a9f2da9 Cleanup Makefile 2019-04-20 08:51:52 +02:00
Patrick Pelissier e6c958c0df Fix data race. 2019-04-19 07:57:10 +02:00
Patrick Pelissier 01ad221972 Rewrite RP so that writers cannot starve and avoid warnings with thread sanitizer. 2019-04-11 20:07:27 +02:00
Patrick Pelissier c269a36e8b Add thread test for RP_CONCURRENT 2019-04-07 19:03:03 +02:00
Patrick Pelissier 95fcd054a3 Fix error in lock orders. 2019-04-04 21:22:37 +02:00
Patrick Pelissier 7760f16260 Fix memory leaks 2019-04-04 08:31:26 +02:00
Patrick Pelissier 6d016d732b Update tags 2019-03-31 22:37:00 +02:00
Patrick Pelissier b9aebf875e Update comments. 2019-03-31 22:36:52 +02:00
Patrick Pelissier 1eb0e8730d Use algorithm with dictionary too. 2019-03-24 08:38:52 +01:00
Patrick Pelissier 7eb26a29f1 Reduce the number of mandatory operators for algorithm:
* EQUAL
* INIT
are not optional (methods depending on them won't be generated
if the operators are not defined).
2019-03-24 08:37:57 +01:00
Patrick Pelissier 0ef051e6d2 Add GLIB to string bench 2019-03-24 08:29:32 +01:00
Patrick Pelissier 0d641f0d17 Update documentation 2019-03-22 07:53:13 +01:00
Patrick Pelissier ce6a7f6cb3 Add missing _it_end for normal dict & export it for both dict 2019-03-15 07:44:58 +01:00
Patrick Pelissier 07b4c1a9f4 Update image 2019-03-12 21:43:33 +01:00
Patrick Pelissier 4d3a82583d Update doc 2019-03-12 21:43:18 +01:00
Patrick Pelissier 2835d53ef1 Clean up code. 2019-03-12 21:42:53 +01:00
Patrick Pelissier 620ecadec1 Update doc 2019-03-12 07:49:04 +01:00
Patrick Pelissier dc803f23bb Add missing const 2019-03-09 16:38:44 +01:00
Patrick Pelissier a6d11fe897 Update doc (ALGO part) 2019-03-09 16:38:25 +01:00
Patrick Pelissier 78b05690e7 Update README 2019-03-07 19:28:46 +01:00
Patrick Pelissier 958a79ad73 Add another example 2019-03-07 19:25:39 +01:00
Patrick Pelissier ead25c905a Factorize common macro for FLA 2019-03-07 07:42:50 +01:00
Patrick Pelissier 97f80450ca Update issue 2019-02-21 20:19:04 +01:00
Patrick Pelissier 8e62537604 Update ISSUE 2019-02-20 11:46:58 +01:00
Patrick Pelissier 7813182e2b Update test. 2019-02-19 20:22:55 +01:00
Patrick Pelissier b199fef674 Update comments and move commented asm into common function. 2019-02-18 11:02:13 +01:00
Patrick Pelissier e27c06c227 Fix regression build with SDS & rapidstring 2019-02-18 10:55:51 +01:00
Patrick Pelissier 41b04f34e2 Fix: Uses of __thread after static keyword 2019-02-18 10:53:27 +01:00
Patrick Pelissier b091f84f90 Update code after benching empty creation of string. 2019-02-18 10:48:03 +01:00
Patrick Pelissier 05ae9f382b Update the barrier used to prevent the compiler from over-optimizing.
Shall be could enought except if using FLTO.
2019-02-18 10:47:28 +01:00
Patrick Pelissier a36efcd888 Create new helper compiler_barrier to prevent compiler from over-optimizing bench. 2019-02-18 10:46:21 +01:00
Patrick Pelissier af2fe9ccf9 Fix issue (sizeof instead of offsetof) 2019-02-17 09:54:56 +01:00
Patrick Pelissier c4a5727c2a Fix deref of NULL pointer. 2019-02-17 09:50:04 +01:00
Patrick Pelissier 31ca762c62 Add a new test case for empty string. 2019-02-17 09:49:49 +01:00
Patrick Pelissier 30bda70319 Fix issue. 2019-02-17 09:36:18 +01:00
Patrick Pelissier 7fa9d375b8 Add bench of small non empty constructor 2019-02-17 08:35:11 +01:00
Patrick Pelissier 91ae3fd4f2 Add memory barrier to limiting the effect of the optimizer on inline implementation 2019-02-16 23:20:36 +01:00
Patrick Pelissier b00d6a9655 Add CSV output to string bench 2019-02-16 22:30:39 +01:00
Patrick Pelissier 013aa58524 Update documentation 2019-02-16 09:01:57 +01:00
Patrick Pelissier 8ce7e0483f Update comment 2019-02-13 08:24:21 +01:00
Patrick Pelissier 582c413cd2 Add VLA allocation compatible with concurrent mempool & gc 2019-02-13 08:19:07 +01:00
Patrick Pelissier 22e16e983b Separate mempool in two concepts:
* A Garbage Collector that centralizes the connexion with the threads
  and registers all mempools
* the mempool that is responsible for alloc/dec of nodes.

It allows having multiple mempools registered in a GC.
2019-02-10 10:26:20 +01:00
Patrick Pelissier 7c0c16260a Update doc 2019-02-05 22:56:02 +01:00
Patrick Pelissier e496fbd152 Add test for string_t + OA DICT 2019-01-27 22:59:03 +01:00
Patrick Pelissier e025de91ab Adding OOR methods for string_t 2019-01-27 22:32:47 +01:00
Patrick Pelissier 69e2fc432f Update doc about limitation of operator TEST_EQUAL 2019-01-27 21:16:19 +01:00
Patrick Pelissier 78ba83ce42 * Fix BOUNDED_STRING_CTE macro. In OOR context, it may create invalid constant that triggers
assumption fault.
* Fix _equal_p in OOR context for bounded string. This method can be called in OOR context,
so the contracts may not be verified.
2019-01-27 17:33:47 +01:00
Patrick Pelissier 6d9b61c119 Reindent 2019-01-27 17:33:17 +01:00
Patrick Pelissier 61cfa5cedd Use of proper contract for BOUNDED_STRING. 2019-01-26 14:00:32 +01:00
Patrick Pelissier 0507d94306 Add test for IO for BOUNDED STRING 2019-01-26 13:39:47 +01:00
Patrick Pelissier 7e8919080b Add IO for BOUNDED STRING 2019-01-26 13:38:54 +01:00
Patrick Pelissier 8406efcaab Add test case of BOUNDED_STRING + OA DICT 2019-01-26 12:03:13 +01:00
Patrick Pelissier 2d87eb1e6a Adding default OOR_EQUAL & OOR_SET for BOUNDED_STRING
to be used in OA dict
2019-01-26 12:02:50 +01:00
Patrick Pelissier 4685aac454 Add test for hash of empty string 2019-01-26 09:10:36 +01:00
Patrick Pelissier 9863a8325c Fix assertion. NULL pointer is accepted for HASH providing the size is 0 2019-01-26 09:10:18 +01:00
Patrick Pelissier b9514cbe72 Fix usage of API with OOR EQUAL of OA Dict 2019-01-25 20:37:33 +01:00
Patrick Pelissier 7b085d18fc Add test case of OA DICT + concurrent 2019-01-25 20:19:52 +01:00
Patrick Pelissier 91e73520f3 Fix issue of non being able to use API_2 with OOR_SET for OA dict 2019-01-25 20:19:31 +01:00
Patrick Pelissier aebf5c83ba Update description of STORED_HASH dict as per remark of #44 2019-01-25 19:47:47 +01:00
Patrick Pelissier 42ff47f511 Fix issue described in #44 (missing types for OA dict) 2019-01-25 19:47:46 +01:00
Patrick Pelissier 746bdf144b Fix warning with CLANG7 2019-01-24 07:44:36 +01:00
Patrick Pelissier 4e8f5f7b51 Add test for queue SPSC 2019-01-21 22:20:28 +01:00
Patrick Pelissier 50d89f71cb Update 2019-01-21 22:06:31 +01:00
Patrick Pelissier d70ef53283 Add _push_force for QUEUE SPSC 2019-01-20 23:59:33 +01:00
Patrick Pelissier 1b6182c1cd Update 2019-01-20 23:57:33 +01:00
Patrick Pelissier 73b50c852a Add bench for SPSC in BULK mode 2019-01-16 05:08:03 +01:00
Patrick Pelissier 063011d8e9 Adding yield in case of failure of push/pop 2019-01-16 04:46:06 +01:00
Patrick Pelissier 0f3bf6ab82 Add _bulk version for SPSC queue. To test/bench 2019-01-15 23:27:02 +01:00
Patrick Pelissier 475836e851 Use of new macro M_CACHELINE_ALIGN 2019-01-15 19:11:10 +01:00
Patrick Pelissier 325ca30c61 Add M_CACHELINE_ALIGN macro 2019-01-15 19:10:39 +01:00
Patrick Pelissier 72e872c768 Remove outdated comment 2019-01-15 07:34:19 +01:00
Patrick Pelissier c2a837b30b Update 2019-01-15 07:32:13 +01:00
Patrick Pelissier 08822ac7d5 Update 2019-01-15 07:25:11 +01:00
Patrick Pelissier 7f9007ca1a Add UPDATE_TYPE 2019-01-11 07:58:20 +01:00
Patrick Pelissier f067cb334c Add missing return after M_MEMORY_FULL 2019-01-05 19:57:53 +01:00
Patrick Pelissier 60ee253fa7 Update 2019-01-05 13:15:50 +01:00
Patrick Pelissier 4642e0b506 Workaround issue of stdatomic on MSYS2/GCC 2019-01-05 00:19:09 +01:00
Patrick Pelissier bd29680b62 Add explanations as comment 2019-01-03 07:45:08 +01:00
Patrick Pelissier c337462af6 Use extension to silent warnings about C11 features used in C99 2019-01-02 22:37:40 +01:00
Patrick Pelissier c990277855 Add extension attribute support 2019-01-02 22:34:39 +01:00
Patrick Pelissier 8870a1c2f9 Remove atomic qualifier for one variable (useless) 2019-01-02 22:16:08 +01:00
Patrick Pelissier 60f1454550 Fix incorrect qualifier position for emulation layer (issue for atomic pointer definition) 2019-01-02 22:15:47 +01:00
Patrick Pelissier 38eb1c26c6 Variable number of threads for concurrent memory pool 2019-01-02 21:48:53 +01:00
Patrick Pelissier af050d0100 Port to C++ madness 2019-01-02 21:21:24 +01:00
Patrick Pelissier 14f3ae5cea Fix issue 2019-01-02 21:21:06 +01:00
Patrick Pelissier f4ed750d39 Add first test case for concurrent memory pool 2019-01-02 21:13:01 +01:00
Patrick Pelissier 4b3adc8d35 Add first WIP Concurrent Memory Allocator 2019-01-02 20:45:06 +01:00
Patrick Pelissier 8b3a4a802c Happy new year! 2019-01-02 18:12:07 +01:00
Patrick Pelissier 8b9f605ffa Add exponential backoff structure & functions 2019-01-02 18:09:16 +01:00
Patrick Pelissier 3c56f24db2 Update analysis 2018-12-29 00:16:50 +01:00
Patrick Pelissier 82dbf60a4c Use of the standard naming for User Defined macro that can customize the code generation. Rename macros WORKER_DISABLE. 2018-12-23 23:49:19 +01:00
201 changed files with 47057 additions and 13643 deletions

No files matched your search

+153
View File
@@ -0,0 +1,153 @@
name: C/C++ CI
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
platform: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: CPU Information
run: lscpu || sysctl -a|grep cpu || echo "CPU information not available"
- name: make check C99
run: make clean && make check -j 2 CC="cc -std=c99 -Wno-unknown-warning-option -Werror"
- name: make check C11
working-directory: ./tests
run: make clean && make check -j 2 CC="cc -std=c11 -Wno-unknown-warning-option -Werror"
- name: make check C++
working-directory: ./tests
run: make clean && make check -j 2 CC="c++ -std=c++11"
build_linux32:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: update package list
run: sudo apt-get update
- name: install multilib
run: sudo apt-get install gcc-multilib g++-multilib
- name: CPU Information
run: lscpu || echo "CPU information not available"
- name: make check C99 (32bits)
working-directory: ./tests
run: make clean && make check -j 2 CC="gcc -m32 -std=c99 -Wno-unknown-warning-option -Werror"
- name: make check C11 (32bits)
working-directory: ./tests
run: make clean && make check -j 2 CC="gcc -m32 -std=c11 -Wno-unknown-warning-option -Werror"
- name: make check C++ (32 bits)
working-directory: ./tests
run: make clean && make check -j 2 CC="g++ -m32 -std=c++11 -Wno-unknown-warning-option "
- name: make check against C++ STL
working-directory: ./tests
run: make clean && make check-stl -j 2
build_linux_tcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: CPU Information
run: lscpu || echo "CPU information not available"
- name: Clone TCC
shell: bash
run: git clone https://repo.or.cz/tinycc.git
- name: Configure, build & install TCC
shell: bash
run: cd tinycc && ./configure --prefix=/tmp/tcc && make && make install
- name: make depend
shell: bash
run: make depend
- name: make check
shell: bash
run: make CC="/tmp/tcc/bin/tcc -std=c99" check
build_linux_sanitize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: make sanitize
working-directory: ./tests
run: make sanitize -j 2
build_windows_mingw:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: make check
shell: bash
run: mingw32-make -j 2 CC="gcc -std=c99 -D__USE_MINGW_ANSI_STDIO=1" check
build_windows_msys2:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: git mingw-w64-x86_64-toolchain make
- name: make check
run: make -j 2 CC="gcc -std=c99 -D__USE_MINGW_ANSI_STDIO=1" check
build_windows_visual:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: make check
shell: cmd
working-directory: ./tests
run: Make-check-cl.bat cl
build_windows_clang_cl:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: make check
shell: cmd
working-directory: ./tests
run: Make-check-cl.bat clang-cl
build_freebsd:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0
with:
usesh: true
run: |
freebsd-version
cd tests
make check -j 2 CC="cc -std=c99 -Wno-unknown-warning-option -Werror" && make clean && make check -j 2 CC="cc -std=c11 -Wno-unknown-warning-option -Werror" LDFLAGS="-lstdthreads" && make clean
# The host should always be linux
build_aarch64:
runs-on: ubuntu-latest
name: Build on aarch64
steps:
- uses: actions/checkout@v3
- uses: uraimo/run-on-arch-action@v2.5.0
name: Run commands on aarch64
id: make
with:
arch: aarch64
distro: bullseye
shell: /bin/sh
run: |
apt-get update -q -y
apt-get install -q -y build-essential git gcc
lscpu
cd tests && make check -j 2 && make clean
+53
View File
@@ -0,0 +1,53 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['cpp']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- name: Autobuild
working-directory: ./tests
run: make exe
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+11
View File
@@ -37,3 +37,14 @@ depend
# Others
other/
a*.dat
config
config.link
*.log
.vscode
.vs
tmp-serial.*
*~
*.gcda
*.gcno
*.gcov
*.synt
+1 -1
View File
@@ -1,6 +1,6 @@
BSD 2-Clause License
Copyright (c) 2017-2018, Patrick Pelissier
Copyright (c) 2017-2023, Patrick Pelissier
All rights reserved.
Redistribution and use in source and binary forms, with or without
+56 -15
View File
@@ -1,24 +1,47 @@
# 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.
# Environnement variable. To customize if needed.
RM=rm -f
MKDIR=mkdir -p
RMDIR=rmdir
INSTALL=install
INSTALL_PROGRAM=${INSTALL}
INSTALL_DATA=${INSTALL} -m 644
# Installation directory
PREFIX=/usr/local
DESTDIR=
# Package name & version.
PACKAGE=m*lib-$(VERSION)
VERSION=0.2.1
PACKAGE=m_lib-$(VERSION)
VERSION=0.7.1
# Define the contain of the distribution tarball
# TODO: Get theses lists from GIT itself.
HEADER=m-algo.h m-array.h m-atomic.h m-bitset.h m-bptree.h m-buffer.h m-concurrent.h m-core.h m-deque.h m-dict.h m-genint.h m-i-list.h m-i-shared.h m-list.h m-mempool.h m-mutex.h m-prioqueue.h m-rbtree.h m-shared.h m-snapshot.h m-string.h m-tuple.h m-variant.h m-worker.h
HEADER=m-algo.h m-array.h m-atomic.h m-bitset.h m-bptree.h m-buffer.h m-c-mempool.h m-concurrent.h m-core.h m-deque.h m-dict.h m-funcobj.h m-genint.h m-i-list.h m-i-shared.h m-list.h m-mempool.h m-thread.h m-mutex.h m-prioqueue.h m-rbtree.h m-serial-bin.h m-serial-json.h m-shared.h m-snapshot.h m-string.h m-tree.h m-try.h m-tuple.h m-variant.h m-worker.h
DOC1=LICENSE README.md
DOC2=doc/API.txt doc/Container.html doc/Container.ods doc/DEV.md doc/ISSUES.org doc/depend.png doc/oplist.png
EXAMPLE=example/ex-array01.c example/ex-array04.c example/ex-dict02.c example/ex-grep01.c example/ex-multi01.c example/ex-rbtree01.c example/ex-array02.c example/ex-buffer01.c example/ex-dict03.c example/ex-list01.c example/ex-multi02.c example/Makefile example/ex-array03.c example/ex-dict01.c example/ex-dict04.c example/ex-mph.c example/ex-multi03.c
TEST=tests/coverage.h tests/test-malgo.c tests/test-mbptree.c tests/test-mdeque.c tests/test-milist.c tests/test-mmutex.c tests/test-mshared.c tests/test-mtuple.c tests/test-obj.h tests/tgen-mdict.c tests/tgen-openmp.c tests/wip-mregister.c tests/dict.txt tests/test-marray.c tests/test-mbuffer.c tests/test-mdict.c tests/test-mlist.c tests/test-mprioqueue.c tests/test-msnapshot.c tests/test-mvariant.c tests/tgen-bitset.c tests/tgen-mlist.c tests/tgen-queue.c tests/Makefile tests/test-mbitset.c tests/test-mcore.c tests/test-mgenint.c tests/test-mmempool.c tests/test-mrbtree.c tests/test-mstring.c tests/test-mworker.c tests/tgen-marray.c tests/tgen-mstring.c tests/tgen-shared.c
DOC2=doc/API.txt doc/Container.html doc/Container.ods doc/depend.png doc/DEV.md doc/ISSUES.org doc/oplist.odp doc/oplist.png
EXAMPLE=example/ex11-algo01.c example/ex11-algo02.c example/ex11-json01.c example/ex11-section.c example/ex-algo02.c example/ex-algo03.c example/ex-algo04.c example/ex-array00.c example/ex-array01.c example/ex-array02.c example/ex-array03.c example/ex-array04.c example/ex-array05.c example/ex-bptree01.c example/ex-buffer01.c example/ex-dict01.c example/ex-dict02.c example/ex-dict03.c example/ex-dict04.c example/ex-grep01.c example/ex-list01.c example/ex-mph.c example/ex-multi01.c example/ex11-multi02.c example/ex-multi03.c example/ex-multi04.c example/ex-multi05.c example/ex-rbtree01.c example/ex11-algo02.json example/ex11-json01.json example/Makefile example/ex-defer01.c example/ex-string01.c example/ex-string02.c example/ex-astar.c example/ex-string03.c example/ex11-tstc.c example/ex-no-stdio.c example/ex11-count-lines.c example/ex11-json-net.c example/ex11-rbtree02.c
TEST=tests/test-malgo.c tests/test-marray.c tests/test-mbitset.c tests/test-mbptree.c tests/test-mbuffer.c tests/test-mcmempool.c tests/test-mconcurrent.c tests/test-mcore.c tests/test-mdeque.c tests/test-mdict.c tests/test-mfuncobj.c tests/test-mgenint.c tests/test-milist.c tests/test-mlist.c tests/test-mmempool.c tests/test-mmutex.c tests/test-mprioqueue.c tests/test-mrbtree.c tests/test-mserial-bin.c tests/test-mserial-json.c tests/test-mshared.c tests/test-msnapshot.c tests/test-mstring.c tests/test-mtuple.c tests/test-mvariant.c tests/test-mworker.c tests/tgen-bitset.c tests/tgen-marray.c tests/tgen-mdict.c tests/tgen-mlist.c tests/tgen-mstring.c tests/tgen-openmp.c tests/tgen-queue.c tests/tgen-shared.c tests/tgen-mserial.c tests/Makefile tests/coverage.h tests/test-obj.h tests/dict.txt tests/fail-chain-oplist.c tests/fail-incompatible.c tests/fail-no-oplist.c tests/test-mishared.c tests/check-array.cpp tests/check-deque.cpp tests/check-dplist.cpp tests/check-list.cpp tests/check-rbtree.cpp tests/check-uset.cpp tests/check-generic.hpp tests/test-mtree.c tests/check-bptree-map.cpp tests/check-bptree-set.cpp tests/check-prioqueue.cpp tests/check-umap.cpp
.PHONY: all test check doc clean distclean depend install uninstall dist
@@ -31,17 +54,22 @@ check:
cd tests && $(MAKE) check
cd example && $(MAKE) all
html: doc
doc: README.md doc/depend.png
checkall:
cd tests && $(MAKE) checkall
cd example && $(MAKE) all
html: README.md
markdown < README.md > README.html
doc: html doc/depend.png
clean:
cd tests && $(MAKE) clean
cd example && $(MAKE) clean
cd bench && $(MAKE) clean
$(RM) README.html depend.dot
$(RM) -r 'm*lib-$(VERSION)'
$(RM) 'm*lib-$(VERSION).tar.bz2'
$(RM) -r 'm_lib-$(VERSION)'
$(RM) 'm_lib-$(VERSION).tar.bz2'
distclean: clean
cd tests && $(MAKE) distclean
@@ -54,7 +82,7 @@ doc/depend.png: $(HEADER)
dot -Tpng depend.dot -o doc/depend.png
optipng -o7 doc/depend.png
dist: $(HEADER) $(DOC1) $(DOC2) $(EXAMPLE) $(TEST) Makefile clean
dist: $(HEADER) $(DOC1) $(DOC2) $(EXAMPLE) $(TEST) Makefile clean versioncheck
$(MKDIR) '$(PACKAGE)'
$(MKDIR) '$(PACKAGE)/doc'
$(MKDIR) '$(PACKAGE)/tests'
@@ -69,9 +97,22 @@ dist: $(HEADER) $(DOC1) $(DOC2) $(EXAMPLE) $(TEST) Makefile clean
distcheck: dist
cd '$(PACKAGE)' && make check
versioncheck:
@if test "$(VERSION)." != `grep M_CORE_VERSION m-core.h |awk '{printf "%d.",$$3 } END {printf "\n"}'` ; then echo "ERROR: Version mismatch between Makefile & HEADERS" ; exit 2 ; fi
@for i in *.h ; do echo $(HEADER) | grep -q $$i ; if test $$? -ne 0 ; then echo "ERROR: Missing header $$i in Makefile" ; exit 3 ; fi ; done
@for i in doc/* ; do echo $(DOC2) | grep -q $$i ; if test $$? -ne 0 ; then echo "ERROR: Missing document $$i in Makefile" ; exit 4 ; fi ; done
@for i in tests/*.c tests/*.txt tests/*.h ; do echo $(TEST) | grep -q $$i ; if test $$? -ne 0 ; then echo "ERROR: Missing test $$i in Makefile" ; exit 5 ; fi ; done
@for i in example/*.c example/*.json ; do echo $(EXAMPLE) | grep -q $$i ; if test $$? -ne 0 ; then echo "ERROR: Missing example $$i in Makefile" ; exit 6 ; fi ; done
@for i in tests/*.cpp tests/*.hpp ; do echo $(TEST) | grep -q $$i ; if test $$? -ne 0 ; then echo "ERROR: Missing test $$i in Makefile" ; exit 7 ; fi ; done
install:
$(MKDIR) $(DESTDIR)$(PREFIX)/include
$(INSTALL_DATA) $(HEADER) $(DESTDIR)$(PREFIX)/include
$(MKDIR) $(DESTDIR)$(PREFIX)/include/m-lib
$(INSTALL_DATA) $(HEADER) $(DESTDIR)$(PREFIX)/include/m-lib
uninstall:
for i in $(HEADER) ; do $(RM) $(DESTDIR)$(PREFIX)/include/$$i ; done
for i in $(HEADER) ; do $(RM) $(DESTDIR)$(PREFIX)/include/m-lib/$$i ; done
$(RMDIR) $(DESTDIR)$(PREFIX)/include/m-lib/
format:
cd example && $(MAKE) ex-string01.exe
for i in $(HEADER) ; do ./example/ex-string01.exe $$i > tmp.h && mv tmp.h $$i ; done
+5949 -2838
View File
File diff suppressed because it is too large. Load diff
+213 -52
View File
@@ -1,20 +1,48 @@
# 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.
CC=cc -std=c11
CXX=c++ -std=c++11
CFLAGS=-O2 -march=native -Wall
XCFLAGS=
CPPFLAGS=-I..
N=4
BENCH_DEF=
RM=rm -rf
.PHONY: all container queue mempool string plain bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-collectionc bench-tommyds bench-flathashmap bench-hopscotchmap bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-mempool bench-string bench-plain
.PHONY: all pgo container queue mempool string plain bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-emhash bench-hopscotchmap bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-mempool bench-string bench-plain bench-rigtorp-mpmc-queue bench-cmc
all: container queue mempool string plain
pgo:
$(MAKE) all XCFLAGS="-fprofile-generate=pgo"
$(MAKE) all XCFLAGS="-fprofile-use=pgo"
#########################################################################
container: bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-collectionc bench-tommyds bench-flathashmap bench-hopscotchmap
container: bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-cmc bench-sparsepp bench-densehashmap bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-emhash bench-hopscotchmap bench-uthash bench-qlibc bench-libsrt bench-nedtries bench-rigtorp-hashmap bench-ctl bench-stc bench-pottery bench-CC
@echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
queue: bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost
queue: bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-rigtorp-mpmc-queue
@echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
mempool: bench-mempool
@@ -32,7 +60,7 @@ plain: bench-plain
bench-mlib:
$(CC) $(CFLAGS) $(CPPFLAGS) -pthread bench-mlib.c -o bench-mlib.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -pthread bench-mlib.c common.c -o bench-mlib.exe
@./bench-mlib.exe 10
@./bench-mlib.exe 11
@./bench-mlib.exe 20
@@ -41,12 +69,14 @@ bench-mlib:
@./bench-mlib.exe 40
@./bench-mlib.exe 41
@./bench-mlib.exe 42
@./bench-mlib.exe 46
@./bench-mlib.exe 47
@./bench-mlib.exe 43
@./bench-mlib.exe 50
@./bench-mlib.exe 51
bench-mlib-mempool:
$(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c -DUSE_MEMPOOL -pthread -o bench-mlib-mempool.exe
$(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c common.c -DUSE_MEMPOOL -pthread -o bench-mlib-mempool.exe
@./bench-mlib-mempool.exe 10
@./bench-mlib-mempool.exe 11
@./bench-mlib-mempool.exe 20
@@ -55,27 +85,31 @@ bench-mlib-mempool:
@./bench-mlib-mempool.exe 40
@./bench-mlib-mempool.exe 41
@./bench-mlib-mempool.exe 42
@./bench-mlib-mempool.exe 46
@./bench-mlib-mempool.exe 47
@./bench-mlib-mempool.exe 43
@./bench-mlib-mempool.exe 50
@./bench-mlib-mempool.exe 51
bench-mlib-thread:
$(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c -DMULTI_THREAD_MEASURE -pthread -o bench-mlib-thread.exe
$(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c common.c -DMULTI_THREAD_MEASURE -pthread -o bench-mlib-thread.exe
@./bench-mlib-thread.exe 60
@./bench-mlib-thread.exe 61
@./bench-mlib-thread.exe 62
@./bench-mlib-thread.exe 63
@./bench-mlib-thread.exe 64
@./bench-mlib-thread.exe 65
@./bench-mlib-thread.exe 66
bench-stl:
$(CXX) $(CFLAGS) $(CPPFLAGS) bench-stl.cpp -o bench-stl.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-stl.cpp common.c -o bench-stl.exe
@./bench-stl.exe 10
@./bench-stl.exe 20
@./bench-stl.exe 30
@./bench-stl.exe 40
@./bench-stl.exe 41
@./bench-stl.exe 42
@./bench-stl.exe 46
@./bench-stl.exe 43
@./bench-stl.exe 50
@./bench-stl.exe 51
@@ -84,7 +118,7 @@ bench-stl:
bench-qt:
@if test -n "$${QT}" ; then $(MAKE) bench-qt0 ; else echo "Nothing to be done for QT." ; fi
bench-qt0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC `PKG_CONFIG_PATH="$${QT}" pkg-config --libs --cflags Qt5Core` bench-qt.cpp -o bench-qt.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -fPIC bench-qt.cpp common.c -o bench-qt.exe `PKG_CONFIG_PATH="$${QT}" pkg-config --libs --cflags Qt5Core`
@./bench-qt.exe 10
@./bench-qt.exe 20
@./bench-qt.exe 30
@@ -97,7 +131,7 @@ bench-qt0:
bench-glib:
@if test -n "$${GLIB}" ; then $(MAKE) bench-glib0 ; else echo "Nothing to be done for GLIB." ; fi
bench-glib0:
$(CC) $(CFLAGS) $(CPPFLAGS) bench-glib.c -o bench-glib.exe `PKG_CONFIG_PATH="$${GLIB}" pkg-config --libs --cflags glib-2.0`
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-glib.c common.c -o bench-glib.exe `PKG_CONFIG_PATH="$${GLIB}" pkg-config --libs --cflags glib-2.0`
@./bench-glib.exe 10
@./bench-glib.exe 20
@./bench-glib.exe 30
@@ -110,7 +144,7 @@ bench-klib:
@if test -n "$${KLIB}" ; then $(MAKE) bench-klib0 ; else echo "Nothing to be done for KLIB." ; fi
bench-klib0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I $${KLIB} bench-klib.c -o bench-klib.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${KLIB} bench-klib.c common.c -o bench-klib.exe
@./bench-klib.exe 10
@./bench-klib.exe 20
@./bench-klib.exe 30
@@ -118,25 +152,32 @@ bench-klib0:
@./bench-klib.exe 41
@./bench-klib.exe 50
# LIBDYNAMIC shall point to the the directory containing the file libdynamic.pc
# CMC shall point to the directory where the CMC main header is
bench-cmc:
@if test -n "$${CMC}" ; then $(MAKE) bench-cmc0 ; else echo "Nothing to be done for CMC." ; fi
bench-cmc0:
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CMC} bench-cmc.c common.c -o bench-cmc.exe
@./bench-cmc.exe 20
@./bench-cmc.exe 30
@./bench-cmc.exe 40
# LIBDYNAMIC shall point to the the source directory where the source is built
bench-libdynamic:
@if test -n "$${LIBDYNAMIC}" ; then $(MAKE) bench-libdynamic0 ; else echo "Nothing to be done for LIBDYNAMIC." ; fi
bench-libdynamic0:
$(CC) $(CFLAGS) $(CPPFLAGS) bench-libdynamic.c -o bench-libdynamic.exe `PKG_CONFIG_PATH="$${LIBDYNAMIC}" pkg-config --libs --cflags libdynamic`
@./bench-libdynamic.exe 10
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-libdynamic.c common.c -o bench-libdynamic.exe -I$${LIBDYNAMIC}/src $${LIBDYNAMIC}/.libs/libdynamic.a
@./bench-libdynamic.exe 20
@./bench-libdynamic.exe 30
@./bench-libdynamic.exe 40
@./bench-libdynamic.exe 41
@./bench-libdynamic.exe 50
# SPARSEPP shall point to the directory where the headers are
bench-sparsepp:
@if test -n "$${SPARSEPP}" ; then $(MAKE) bench-sparsepp0 ; else echo "Nothing to be done for SPARSEPP." ; fi
bench-sparsepp0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${SPARSEPP}" -I "$${SPARSEPP}/.." bench-sparsepp.cpp -o bench-sparsepp.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${SPARSEPP}" -I "$${SPARSEPP}/.." bench-sparsepp.cpp common.c -o bench-sparsepp.exe
@./bench-sparsepp.exe 41
@./bench-sparsepp.exe 42
@./bench-sparsepp.exe 43
@@ -146,17 +187,17 @@ bench-densehashmap:
@if test -n "$${DENSEHASHMAP}" ; then $(MAKE) bench-densehashmap0 ; else echo "Nothing to be done Google DENSEHASHMAP." ; fi
bench-densehashmap0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${DENSEHASHMAP}" -I "$${DENSEHASHMAP}/.." bench-densehashmap.cpp -o bench-densehashmap.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${DENSEHASHMAP}" -I "$${DENSEHASHMAP}/.." bench-densehashmap.cpp common.c -o bench-densehashmap.exe
@./bench-densehashmap.exe 41
@./bench-densehashmap.exe 42
@./bench-densehashmap.exe 43
# COLLECTIONC shall point to the directory where the 'src' directory is.
# COLLECTIONC shall point to the directory where it is installed
bench-collectionc:
@if test -n "$${COLLECTIONC}" ; then $(MAKE) bench-collectionc0 ; else echo "Nothing to be done for COLLECTIONC." ; fi
bench-collectionc0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${COLLECTIONC}/include" -L "$${COLLECTIONC}" -static bench-collectionc.c -lcollectc -o bench-collectionc.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${COLLECTIONC}/include/collectc" bench-collectionc.c common.c "$${COLLECTIONC}/lib/libcollectc.a" -o bench-collectionc.exe
@./bench-collectionc.exe 10
@./bench-collectionc.exe 20
@./bench-collectionc.exe 30
@@ -169,7 +210,7 @@ bench-tommyds:
@if test -n "$${TOMMYDS}" ; then $(MAKE) bench-tommyds0 ; else echo "Nothing to be done for TOMMYDS." ; fi
bench-tommyds0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${TOMMYDS}" bench-tommyds.c $${TOMMYDS}/tommyds/tommyarray.c $${TOMMYDS}/tommyds/tommylist.c $${TOMMYDS}/tommyds/tommytree.c $${TOMMYDS}/tommyds/tommyhashlin.c -o bench-tommyds.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${TOMMYDS}" bench-tommyds.c $${TOMMYDS}/tommyds/tommyarray.c $${TOMMYDS}/tommyds/tommylist.c $${TOMMYDS}/tommyds/tommytree.c $${TOMMYDS}/tommyds/tommyhashlin.c common.c -o bench-tommyds.exe
@./bench-tommyds.exe 10
@./bench-tommyds.exe 20
@./bench-tommyds.exe 30
@@ -181,17 +222,40 @@ bench-flathashmap:
@if test -n "$${FLATHASHMAP}" ; then $(MAKE) bench-flathashmap0 ; else echo "Nothing to be done for FLATHASHMAP." ; fi
bench-flathashmap0:
$(CXX) -std=c++14 $(CFLAGS) $(CPPFLAGS) -I "$${FLATHASHMAP}" bench-flathashmap.cpp -o bench-flathashmap.exe
$(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${FLATHASHMAP}" bench-flathashmap.cpp common.c -o bench-flathashmap.exe
@./bench-flathashmap.exe 41
@./bench-flathashmap.exe 42
@./bench-flathashmap.exe 46
@./bench-flathashmap.exe 43
# EMILIB shall point to the directory where the headers are
bench-emilib:
@if test -n "$${EMILIB}" ; then $(MAKE) bench-emilib0 ; else echo "Nothing to be done for EMILIB." ; fi
bench-emilib0:
$(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${EMILIB}" bench-emilib.cpp common.c -o bench-emilib.exe
@./bench-emilib.exe 41
@./bench-emilib.exe 42
@./bench-emilib.exe 46
@./bench-emilib.exe 43
# EMHASh shall point to the directory where the headers are
bench-emhash:
@if test -n "$${EMHASH}" ; then $(MAKE) bench-emhash0 ; else echo "Nothing to be done for EMHASH." ; fi
bench-emhash0:
$(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${EMHASH}" bench-emhash.cpp common.c -o bench-emhash.exe
@./bench-emhash.exe 41
@./bench-emhash.exe 42
@./bench-emhash.exe 46
@./bench-emhash.exe 43
# HOPSCOTCHMAP shall point to the directory where the source are
bench-hopscotchmap:
@if test -n "$${HOPSCOTCHMAP}" ; then $(MAKE) bench-hopscotchmap0 ; else echo "Nothing to be done for HOPSCOTCHMAP." ; fi
bench-hopscotchmap0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${HOPSCOTCHMAP}" bench-hopscotchmap.cpp -o bench-hopscotchmap.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${HOPSCOTCHMAP}/include/tsl" bench-hopscotchmap.cpp common.c -o bench-hopscotchmap.exe
@./bench-hopscotchmap.exe 41
@./bench-hopscotchmap.exe 42
@./bench-hopscotchmap.exe 43
@@ -201,12 +265,11 @@ bench-uthash:
@if test -n "$${UTHASH}" ; then $(MAKE) bench-uthash0 ; else echo "Nothing to be done for UTHASH." ; fi
bench-uthash0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${UTHASH}" bench-uthash.c -o bench-uthash.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${UTHASH}" bench-uthash.c common.c -o bench-uthash.exe
@./bench-uthash.exe 10
@./bench-uthash.exe 20
@./bench-uthash.exe 40
@./bench-uthash.exe 41
@./bench-uthash.exe 42
@./bench-uthash.exe 43
@./bench-uthash.exe 50
# QLIBC shall point to the directory where the library is installed.
@@ -214,24 +277,18 @@ bench-qlibc:
@if test -n "$${QLIBC}" ; then $(MAKE) bench-qlibc0 ; else echo "Nothing to be done for QLIBC." ; fi
bench-qlibc0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${QLIBC}/include" -L "$${QLIBC}/lib" -lqlibc -pthread bench-qlibc.c -o bench-qlibc.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${QLIBC}/include" -L "$${QLIBC}/lib" -lqlibc -pthread bench-qlibc.c common.c -o bench-qlibc.exe
@LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 10
@LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 20
@LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 30
@LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 42
@LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 41
# LIBSRT shall point to the directory where the source are
# LIBSRT shall point to the directory where it is installed
bench-libsrt:
@if test -n "$${LIBSRT}" ; then $(MAKE) bench-libsrt0 ; else echo "Nothing to be done for LIBSRT." ; fi
bench-libsrt0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${LIBSRT}/src" bench-libsrt.c -o bench-libsrt.exe $${LIBSRT}/libsrt.a
@./bench-libsrt.exe 10
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${LIBSRT}/src" bench-libsrt.c common.c -o bench-libsrt.exe $${LIBSRT}/src/.libs/libsrt.a
@./bench-libsrt.exe 20
@./bench-libsrt.exe 41
@./bench-libsrt.exe 42
@./bench-libsrt.exe 43
@./bench-libsrt.exe 50
@@ -240,7 +297,7 @@ bench-libsrt0:
bench-liblfds:
@if test -n "$${LIBLFDS}" ; then $(MAKE) bench-liblfds0 ; else echo "Nothing to be done for LIBLFDS." ; fi
bench-liblfds0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${LIBLFDS}/inc" -Wno-unknown-pragmas bench-liblfds.c -o bench-liblfds.exe $${LIBLFDS}/bin/liblfds711.a -lpthread
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${LIBLFDS}/inc" -Wno-unknown-pragmas bench-liblfds.c common.c -DMULTI_THREAD_MEASURE -o bench-liblfds.exe $${LIBLFDS}/bin/liblfds711.a -lpthread
@LD_LIBRARY_PATH="$${LIBLFDS}/bin:$${LD_LIBRARY_PATH}" ./bench-liblfds.exe 60
@@ -249,36 +306,118 @@ bench-liblfds0:
bench-concurrentqueue:
@if test -n "$${CONCURRENTQUEUE}" ; then $(MAKE) bench-concurrentqueue0 ; else echo "Nothing to be done for CONCURRENTQUEUE." ; fi
bench-concurrentqueue0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${CONCURRENTQUEUE}/" bench-concurrentqueue.cpp -o bench-concurrentqueue.exe -lpthread
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${CONCURRENTQUEUE}/" bench-concurrentqueue.cpp common.c -DMULTI_THREAD_MEASURE -o bench-concurrentqueue.exe -lpthread
@./bench-concurrentqueue.exe 60
# XXHASH shall point to the source directory of xxhash
# The library shall be built.
bench-xxhash:
@if test -n "$${XXHASH}" ; then $(MAKE) bench-xxhash0 ; else echo "Nothing to be done for XXHASH." ; fi
bench-xxhash0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${XXHASH}/" bench-xxhash.c "$${XXHASH}/libxxhash.a" -o bench-xxhash.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${XXHASH}/" bench-xxhash.c common.c "$${XXHASH}/libxxhash.a" -o bench-xxhash.exe
@./bench-xxhash.exe 70
# BOOST shall point to the header location.
bench-boost:
@if test -n "$${BOOST}" ; then $(MAKE) bench-boost0 ; else echo "Nothing to be done for BOOST." ; fi
bench-boost0:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${BOOST}" bench-boost.cpp -o bench-boost.exe -lpthread
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${BOOST}" bench-boost.cpp common.c -DMULTI_THREAD_MEASURE -o bench-boost.exe -lpthread
@./bench-boost.exe 60
# NEDTRIES shall point to the header location.
bench-nedtries:
@if test -n "$${NEDTRIES}" ; then $(MAKE) bench-nedtries0 ; else echo "Nothing to be done for NEDTRIES." ; fi
bench-nedtries0:
$(CC) $(CFLAGS) $(CPPFLAGS) -I "$${NEDTRIES}" bench-nedtries.c -o bench-nedtries.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${NEDTRIES}" bench-nedtries.c common.c -o bench-nedtries.exe
@./bench-nedtries.exe 40
@./bench-nedtries.exe 45
# RIGTORP_HASHMAP shall point to the directory where the headers are
bench-rigtorp-hashmap:
@if test -n "$${RIGTORP_HASHMAP}" ; then $(MAKE) bench-rigtorp-hashmap0 ; else echo "Nothing to be done for RIGTORP_HASHMAP." ; fi
bench-rigtorp-hashmap0:
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RIGTORP_HASHMAP}/include" bench-rigtorp-hashmap.cpp common.c -o bench-rigtorp-hashmap.exe
@./bench-rigtorp-hashmap.exe 42
@./bench-rigtorp-hashmap.exe 41
@./bench-rigtorp-hashmap.exe 43
# RIGTORP_MPMC_QUEUE shall point to the directory where the headers are
bench-rigtorp-mpmc-queue:
@if test -n "$${RIGTORP_MPMC_QUEUE}" ; then $(MAKE) bench-rigtorp-mpmc-queue0 ; else echo "Nothing to be done for RIGTORP_MPMC_QUEUE." ; fi
bench-rigtorp-mpmc-queue0:
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RIGTORP_MPMC_QUEUE}" bench-rigtorp-mpmcqueue.cpp common.c -DMULTI_THREAD_MEASURE -o bench-mpmcqueue.exe -lpthread
@./bench-mpmcqueue.exe 60
# CTL shall point to the source directory (not where the headers are)
bench-ctl:
@if test -n "$${CTL}" ; then $(MAKE) bench-ctl0 ; else echo "Nothing to be done for CTL." ; fi
bench-ctl0:
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CTL} bench-ctl.c common.c -o bench-ctl.exe
@./bench-ctl.exe 10
@./bench-ctl.exe 20
@./bench-ctl.exe 30
@./bench-ctl.exe 40
@./bench-ctl.exe 50
# STC shall point to the source directory (not where the headers are)
bench-stc:
@if test -n "$${STC}" ; then $(MAKE) bench-stc0 ; else echo "Nothing to be done for STC." ; fi
bench-stc0:
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${STC}/include bench-stc.c common.c -o bench-stc.exe
@./bench-stc.exe 10
@./bench-stc.exe 20
@./bench-stc.exe 30
@./bench-stc.exe 40
@./bench-stc.exe 41
@./bench-stc.exe 50
# POTTERY shall point to the source directory (not where the headers are)
bench-pottery:
@if test -n "$${POTTERY}" ; then $(MAKE) bench-pottery0 ; else echo "Nothing to be done for POTTERY." ; fi
bench-pottery0:
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DPOTTERY_AVAILABLE=1 -I $${POTTERY}/include bench-pottery.c common.c -o bench-pottery.exe
@./bench-pottery.exe 10
@./bench-pottery.exe 20
@./bench-pottery.exe 30
@./bench-pottery.exe 40
@./bench-pottery.exe 41
@./bench-pottery.exe 50
# CCLIB shall point to the source directory of CC (where the headers are)
bench-CC:
@if test -n "$${CCLIB}" ; then $(MAKE) bench-CC0 ; else echo "Nothing to be done for CC." ; fi
bench-CC0:
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CCLIB}/ bench-CC.c common.c -o bench-CC.exe
@./bench-CC.exe 10
@./bench-CC.exe 20
@./bench-CC.exe 40
@./bench-CC.exe 41
############################################################################
bench-mlib-json: bench-mlib
@./bench-mlib.exe 110
@./bench-mlib.exe 111
@./bench-mlib.exe 112
bench-rapidjson:
@if test -n "$${RAPIDJSON}" ; then $(MAKE) bench-rapidjson0 ; else echo "Nothing to be done for RAPIDJSON." ; fi
bench-rapidjson0:
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RAPIDJSON}/" bench-rapidjson.cpp common.c -o bench-rapidjson.exe
@./bench-rapidjson.exe 110
@./bench-rapidjson.exe 111
@./bench-rapidjson.exe 112
############################################################################
bench-plain:
$(CC) $(CFLAGS) $(CPPFLAGS) bench-plain-c.c -o bench-plain-c.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-plain-c.c -o bench-plain-c.exe
@./bench-plain-c.exe
############################################################################
@@ -286,13 +425,13 @@ bench-plain:
bench-mempool:
@if test -n "$${BOOST}" ; then if test -n "$${GLIB}" ; then make bench-mempool0 BENCH_DEF="-DUSE_BOOST -DUSE_GLIB `pkg-config --libs --cflags glib-2.0` -lboost_system" ; else make bench-mempool0 BENCH_DEF="-DUSE_BOOST -lboost_system" ; fi ; else if test -n "$${GLIB}" ; then make bench-mempool0 BENCH_DEF="-DUSE_GLIB `pkg-config --libs --cflags glib-2.0`" ; else make bench-mempool0 ; fi ; fi
bench-mempool0:
$(CXX) $(CFLAGS) $(CPPFLAGS) pool.cc $(BENCH_DEF) -o bench-mempool.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) pool.cc $(BENCH_DEF) -o bench-mempool.exe
@./bench-mempool.exe
############################################################################
bench-maxdict:
$(CC) $(CFLAGS) $(CPPFLAGS) max-dict.c -o bench-max-dict.exe
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) max-dict.c -o bench-max-dict.exe
@./bench-max-dict.exe
############################################################################
@@ -300,27 +439,49 @@ bench-maxdict:
# BSTRLIB shall point to the BSTRLIB sources
# LIBSRT shall point to the LIBSRT sources
bench-string:
@if test -n "$${BSTRLIB}" ; then $(MAKE) bench-string-with BENCH_DEF="-DBENCH_CAN_USE_BSTRLIB -I ${BSTRLIB} $${BSTRLIB}/obj/bstrlib.o $${BSTRLIB}/obj/bstraux.o $${BSTRLIB}/obj/bstrwrap.o" ; else $(MAKE) bench-string-with ; fi
@if test -n "$${BSTRLIB}" ; then $(MAKE) bench-string-step1 BENCH_DEF="-DBENCH_CAN_USE_BSTRLIB -I ${BSTRLIB} $${BSTRLIB}/obj/bstrlib.o $${BSTRLIB}/obj/bstraux.o $${BSTRLIB}/obj/bstrwrap.o" ; else $(MAKE) bench-string-step1 ; fi
bench-string-with:
@if test -n "$${LIBSRT}" ; then $(MAKE) bench-string-with2 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_LIBSRT -I$${LIBSRT}/src $${LIBSRT}/libsrt.a" ; else $(MAKE) bench-string-with2 BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-step1:
@if test -n "$${LIBSRT}" ; then $(MAKE) bench-string-step2 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_LIBSRT -I$${LIBSRT}/src $${LIBSRT}/src/.libs/libsrt.a" ; else $(MAKE) bench-string-step2 BENCH_DEF="$(BENCH_DEF)"; fi
#NOTE: Need to build by hand sds.o since it is not build by default and sds.c is not compatible with C++
bench-string-with2:
@if test -n "$${SDS}" ; then $(MAKE) bench-string-with3 BENCH_DEF="$(BENCH_DEF) -fpermissive -DBENCH_CAN_USE_SDS -I$${SDS}/ $${SDS}/sds.o" ; else $(MAKE) bench-string-with3 BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-step2:
@if test -n "$${SDS}" ; then $(MAKE) bench-string-step4 BENCH_DEF="$(BENCH_DEF) -fpermissive -DBENCH_CAN_USE_SDS -I$${SDS}/ $${SDS}/sds.o" ; else $(MAKE) bench-string-step4 BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-with3:
@if test -n "$${RAPIDSTRING}" ; then $(MAKE) bench-string-exe BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_RAPIDSTRING -I$${RAPIDSTRING}/ " ; else $(MAKE) bench-string-exe BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-step4:
@if test -n "$${GLIB}" ; then $(MAKE) bench-string-step5 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_GLIB $$(pkg-config --cflags --libs glib-2.0)" ; else $(MAKE) bench-string-step5 BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-exe:
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${BSTRLIB}" -DBENCH_CAN_USE_STL -DBENCH_CAN_USE_MSTARLIB bench-string.cpp -o bench-string.exe $(BENCH_DEF)
bench-string-step5:
@if test -n "$${POTTERY}" ; then $(MAKE) bench-string-step6 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_POTTERY -I$${POTTERY}/include -I$${POTTERY}/util/ $${POTTERY}/util/pottery/string/string.c" ; else $(MAKE) bench-string-step6 BENCH_DEF="$(BENCH_DEF)"; fi
bench-string-step6:
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DBENCH_CAN_USE_STL -DBENCH_CAN_USE_MSTARLIB bench-string.cpp common.c $(BENCH_DEF) -o bench-string.exe
$(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DBENCH_CAN_USE_STL -DBENCH_CAN_USE_MSTARLIB bench-string-2.cpp common.c $(BENCH_DEF) -o bench-string-2.exe
@./bench-string.exe
@./bench-string-2.exe 2000000 0
@./bench-string-2.exe 2000000 1
@./bench-string-2.exe 2000000 2
@./bench-string-2.exe 2000000 4
@./bench-string-2.exe 2000000 5
bench-string-pgo:
$(MAKE) bench-string XCFLAGS="-fprofile-generate=pgo"
$(MAKE) bench-string XCFLAGS="-fprofile-use=pgo"
############################################################################
bench-find-sort:
g++ bench-find-sort.cpp -O2 -march=native -std=c++11 -I.. -g common.c -o bench-find-sort.exe
./bench-find-sort.exe 10000000
############################################################################
clean:
rm -f *.o bench-*.exe bench-*.s *~ massif.out.*
$(RM) *.o bench-*.exe
$(RM) bench-*.s *~ massif.out.*
$(RM) plot-*.dat
$(RM) pgo
$(RM) tmp-serial.*
cd nucleotide && $(MAKE) clean
############################################################################
+140
View File
@@ -0,0 +1,140 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "common.h"
#include "cc.h"
/********************************************************************************************/
static void test_array(size_t n)
{
vec( unsigned int ) a1, a2;
init(&a1);
init(&a2);
for(size_t i = 0; i < n; i++) {
push(&a1, rand_get() );
push(&a2, rand_get() );
}
unsigned int s = 0;
for(unsigned long i = 0; i < n; i++) {
s += *get(&a1, i ) * *get(&a2, i );
}
g_result = s;
cleanup(&a1);
cleanup(&a2);
}
/********************************************************************************************/
static void test_list(size_t n)
{
list( unsigned int ) a1, a2;
init(&a1);
init(&a2);
for(size_t i = 0; i < n; i++) {
push(&a1, rand_get() );
push(&a2, rand_get() );
}
unsigned int s = 0;
for(unsigned *it1 = first( &a1 ), *it2 = first( &a2 ); it1 != end( &a1 ); it1 = next( &a1, it1 ), it2 = next(&a2, it2) ) {
s += *it1 * *it2;
}
g_result = s;
cleanup(&a1);
cleanup(&a2);
}
/********************************************************************************************/
static void
test_dict(size_t n)
{
map( unsigned long, unsigned long ) dict;
init(&dict);
for (size_t i = 0; i < n; i++) {
unsigned long value = rand_get();
unsigned long key = rand_get();
insert(&dict, key, value);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long key = rand_get();
const unsigned long *val = get(&dict, key);
if (val != NULL)
s += *val;
}
g_result = s;
cleanup(&dict);
}
/********************************************************************************************/
typedef struct {
char a[256];
} char_array_t;
static inline void char_init (char_array_t *a) { a->a[0] = 0; }
static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); }
static inline bool char_equal_p (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a)==0; }
static inline bool char_cmp (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a); }
static inline void char_clear (char_array_t *a) { (void)a; }
static inline size_t char_hash(const char_array_t *a) {
size_t hash = 0;
const char *s = a->a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
}
#define CC_DTOR char_array_t, { char_clear(&val); }
#define CC_CMPR char_array_t, { return char_cmp(&val_1, &val_2); }
#define CC_HASH char_array_t, { return char_hash(&val); }
#include "cc.h"
static void
test_dict_big(size_t n)
{
map( char_array_t, char_array_t) dict;
init(&dict);
for (size_t i = 0; i < n; i++) {
char_array_t s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
insert(&dict, s1, s2);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_t s1;
sprintf(s1.a, "%u", rand_get());
const char_array_t *val = get(&dict, s1);
if (val != NULL)
s ++;
}
g_result = s;
cleanup(&dict);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
};
int main(int argc, const char *argv[])
{
test("CC", numberof(table), table, argc, argv);
exit(0);
}
+6 -8
View File
@@ -6,11 +6,8 @@
#include <boost/lockfree/queue.hpp>
#include "m-mutex.h"
#define MULTI_THREAD_MEASURE
#include "common.h"
/********************************************************************************************/
boost::lockfree::queue<unsigned int, boost::lockfree::capacity<4*64>> g_buff;
boost::lockfree::queue<unsigned long long, boost::lockfree::capacity<4*64>> g_final;
@@ -51,7 +48,7 @@ static void prod(void *arg)
}
}
static void test_buffer(size_t n)
static void test_queue(size_t n)
{
const int cpu_count = get_cpu_count();
const int prod_count = cpu_count/2;
@@ -88,11 +85,12 @@ static void test_buffer(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 60, "Queue MPMC", 1000000, 0, test_queue, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 60)
test_function("Buffer time", 1000000, test_buffer);
test("BOOST-LOCKFREE", numberof(table), table, argc, argv);
exit(0);
}
+204
View File
@@ -0,0 +1,204 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "macro_collections.h"
#include "common.h"
/********************************************************************************************/
// CMC list are dynamic array
#define MY_LIST_PARAMS (list_uint, list_uint_s, , , unsigned int)
C_MACRO_COLLECTIONS_EXTENDED(CMC, LIST, MY_LIST_PARAMS, (STR))
struct list_uint_s_fval list_fval = { .cmp = NULL,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = NULL,
.pri = NULL };
static void test_array(size_t n)
{
struct list_uint_s *a1 = list_uint_new(1, &list_fval);
struct list_uint_s *a2 = list_uint_new(1, &list_fval);
for(size_t i = 0; i < n; i++) {
list_uint_push_back(a1, rand_get() );
list_uint_push_back(a2, rand_get() );
}
unsigned int s = 0;
for(unsigned long i = 0; i < n; i++) {
s += list_uint_get(a1, i ) * list_uint_get(a2, i );
}
g_result = s;
list_uint_free(a1);
list_uint_free(a2);
}
/********************************************************************************************/
#define my_cmp(a,b) ( (a) < (b) ? -1 : (a) > (b) )
#define MY_TMAP_PARAMS (tree_ulong, tree_ulong_s, , unsigned long, bool)
C_MACRO_COLLECTIONS_EXTENDED(CMC, TREEMAP, MY_TMAP_PARAMS, (STR))
int cmp_ulong(unsigned long a, unsigned long b) { return my_cmp(a,b); }
struct tree_ulong_s_fkey tree_fkey = { .cmp = cmp_ulong,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = NULL,
.pri = NULL };
struct tree_ulong_s_fval tree_fval = { .cmp = NULL,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = NULL,
.pri = NULL };
static void test_rbtree(size_t n)
{
struct tree_ulong_s *tree;
tree = tree_ulong_new(&tree_fkey, &tree_fval);
for (size_t i = 0; i < n; i++) {
unsigned long j = rand_get();
tree_ulong_insert(tree, j, true);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long j = rand_get();
if (tree_ulong_get_ref(tree, j) != 0)
s+= j;
}
g_result = s;
tree_ulong_free(tree);
}
/********************************************************************************************/
#define hash_func(a) kh_int64_hash_func(a)
size_t hash_ulong(unsigned long a)
{
return ( (a) >> 33 ) ^ (a) ^ ((a) << 11);
}
#define MY_DICT_PARAMS (hmap, hmap_s, , unsigned long, unsigned long)
C_MACRO_COLLECTIONS_EXTENDED(CMC, HASHMAP, MY_DICT_PARAMS, (STR))
struct hmap_s_fkey hmap_fkey = { .cmp = cmp_ulong,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = hash_ulong,
.pri = NULL };
struct hmap_s_fval hmap_fval = { .cmp = NULL,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = NULL,
.pri = NULL };
static void
test_dict(size_t n)
{
struct hmap_s *dict = hmap_new(16, 0.7, &hmap_fkey, &hmap_fval);
for (size_t i = 0; i < n; i++) {
hmap_insert(dict, rand_get(), rand_get());
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long *val = hmap_get_ref(dict, rand_get());
if (val != 0)
s += *val;
}
g_result = s;
hmap_free(dict);
}
/********************************************************************************************/
#if 0 // Not working issue in using not integer types
typedef struct {
char a[256];
} char_array_t;
static inline int char_cmp (const char_array_t a, const char_array_t b) { return strcmp(a.a,b.a); }
static inline size_t char_hash(const char_array_t a) {
size_t hash = 0;
const char *s = a.a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
}
#define MY_DICTB_PARAMS (bhmap, bhmap_s, , char_array_t, char_array_t)
C_MACRO_COLLECTIONS_EXTENDED(CMC, HASHMAP, MY_DICT_PARAMS, (STR))
struct bhmap_s_fkey bhmap_fkey = { .cmp = char_cmp,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = char_hash,
.pri = NULL };
struct bhmap_s_fval bhmap_fval = { .cmp = NULL,
.cpy = NULL,
.str = NULL,
.free = NULL,
.hash = NULL,
.pri = NULL };
static void
test_dict_big(size_t n)
{
struct bhmap_s *dict = bhmap_new(16, 0.7, &bhmap_fkey, &bhmap_fval);
for (size_t i = 0; i < n; i++) {
char_array_t s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
bhmap_insert(dict, s1, s2);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_t s1;
sprintf(s1.a, "%u", rand_get() );
char_array_t *val = bhmap_get_ref(dict, s1);
if (val != 0)
s ++;
}
g_result = s;
bhmap_free(dict);
}
#endif
/********************************************************************************************/
const config_func_t table[] = {
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
//{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
};
int main(int argc, const char *argv[])
{
test("CMC", numberof(table), table, argc, argv);
exit(0);
}
+10 -13
View File
@@ -250,20 +250,17 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("CollectionC", numberof(table), table, argc, argv);
exit(0);
}
+6 -8
View File
@@ -6,11 +6,8 @@
#include "concurrentqueue.h"
#include "m-mutex.h"
#define MULTI_THREAD_MEASURE
#include "common.h"
/********************************************************************************************/
moodycamel::ConcurrentQueue<unsigned int> g_buff;
moodycamel::ConcurrentQueue<unsigned long long> g_final;
@@ -51,7 +48,7 @@ static void prod(void *arg)
}
}
static void test_buffer(size_t n)
static void test_queue(size_t n)
{
const int cpu_count = get_cpu_count();
const int prod_count = cpu_count/2;
@@ -88,11 +85,12 @@ static void test_buffer(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 60, "Queue MPMC", 1000000, 0, test_queue, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 60)
test_function("Buffer time", 1000000, test_buffer);
test("CONCURRENT-QUEUE", numberof(table), table, argc, argv);
exit(0);
}
+183
View File
@@ -0,0 +1,183 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "m-core.h"
#include "common.h"
typedef unsigned int uint;
typedef unsigned long ulong;
/********************************************************************************************/
#define POD
#define T uint
#include "ctl/vector.h"
static void test_array(size_t n)
{
vec_uint a1 = vec_uint_init();
vec_uint a2 = vec_uint_init();
for(size_t i = 0; i < n; i++) {
vec_uint_push_back(&a1, rand_get() );
vec_uint_push_back(&a2, rand_get() );
}
unsigned int s = 0;
for(unsigned long i = 0; i < n; i++) {
s += *vec_uint_at(&a1, i ) * *vec_uint_at(&a2, i );
}
g_result = s;
vec_uint_free(&a1);
vec_uint_free(&a2);
}
/********************************************************************************************/
#define POD
#define T uint
#include "ctl/forward_list.h"
static void test_list (size_t n)
{
slist_uint a1 = slist_uint_init();
slist_uint a2 = slist_uint_init();
for(size_t i = 0; i < n; i++) {
slist_uint_push_front(&a1, rand_get());
slist_uint_push_front(&a2, rand_get());
}
unsigned int s = 0;
slist_uint_it it1 = slist_uint_begin(&a1);
slist_uint_it it2 = slist_uint_begin(&a2);
for( ; !slist_uint_it_done(&it1) ;
slist_uint_it_next(&it1), slist_uint_it_next(&it2)) {
s += *slist_uint_it_ref(&it1) * *slist_uint_it_ref(&it2);
}
g_result = s;
slist_uint_free(&a1);
slist_uint_free(&a2);
}
/********************************************************************************************/
#define POD
#define T ulong
#include "ctl/set.h"
static inline int
int_cmp(ulong *a, ulong *b) {
return *a < *b;
}
static void test_rbtree(size_t n)
{
set_ulong tree = set_ulong_init (int_cmp);
for (size_t i = 0; i < n; i++) {
set_ulong_insert (&tree, rand_get() );
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long j = rand_get();
if (set_ulong_find_node(&tree, j) != NULL)
s+= j;
}
g_result = s;
set_ulong_free(&tree);
}
/********************************************************************************************/
typedef struct {
unsigned long key;
unsigned long value;
} pair_ulong;
// Use of M*LIB hash function
static inline size_t
pair_ulong_hash(pair_ulong *a)
{
return M_HASH_DEFAULT(a->key);
}
static inline int
pair_ulong_equal(pair_ulong *a, pair_ulong *b)
{
return a->key == b->key;
}
static inline void
pair_ulong_free(pair_ulong *a) {
(void) a;
}
static inline pair_ulong
pair_ulong_copy(pair_ulong *self) {
return (pair_ulong) { .key = self->key, .value = self->value };
}
#define T pair_ulong
#include <ctl/unordered_map.h>
static void
test_dict(size_t n)
{
umap_pair_ulong dict = umap_pair_ulong_init(pair_ulong_hash, pair_ulong_equal);
for (size_t i = 0; i < n; i++) {
unsigned long value = rand_get();
unsigned long key = rand_get();
umap_pair_ulong_insert(&dict, (pair_ulong) { key, value });
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
umap_pair_ulong_it it = umap_pair_ulong_find(&dict, (pair_ulong) { rand_get() , 0 } );
if (!umap_pair_ulong_it_done(&it) )
s += it.ref->value;
}
g_result = s;
umap_pair_ulong_free(&dict);
}
/********************************************************************************************/
#define POD
#define T float
#include "ctl/vector.h"
static void test_sort(size_t n)
{
vec_float a1 = vec_float_init();
for(size_t i = 0; i < n; i++) {
vec_float_push_back(&a1, rand_get());
}
vec_float_sort(&a1);
g_result = *vec_float_at(&a1, 0);
vec_float_free(&a1);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 50, "Sort", 10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
test("CTL", numberof(table), table, argc, argv);
exit(0);
}
+7 -7
View File
@@ -131,14 +131,14 @@ test_dict_str(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS(u) time", 1000000, test_dict_str);
test("DENSE-HASPMAP", numberof(table), table, argc, argv);
exit(0);
}
+138
View File
@@ -0,0 +1,138 @@
#define NDEBUG
#include <vector>
#include <list>
#include <iterator>
#include <map>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "hash_table7.hpp"
using namespace emhash7;
using namespace std;
#include "common.h"
/********************************************************************************************/
static void
test_dict2(size_t n)
{
HashMap<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[rand_get()] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
HashMap<unsigned long, unsigned long>::iterator it = dict.find(rand_get());
if (it != dict.end())
s += it->second;
}
g_result = s;
}
static void
test_dict2_linear(size_t n)
{
HashMap<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[i] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
HashMap<unsigned long, unsigned long>::iterator it = dict.find(i);
if (it != dict.end())
s += it->second;
}
g_result = s;
}
/********************************************************************************************/
struct char_array_s {
char a[256];
char_array_s () { a[0] = 0 ; }
char_array_s ( const char_array_s & other) { strcpy(a, other.a); }
bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; }
};
namespace std {
template <> struct hash<char_array_s> {
std::size_t operator()(const char_array_s &k) const {
size_t hash = 0;
const char *s = k.a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
};
};
}
static void
test_dict_big(size_t n)
{
HashMap<char_array_s, char_array_s> dict;
for (size_t i = 0; i < n; i++) {
char_array_s s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_s s1;
sprintf(s1.a, "%u", rand_get());
HashMap<char_array_s, char_array_s>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
static void
test_dict_str(size_t n)
{
HashMap<string, string> dict;
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
string s2 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
HashMap<string, string>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0},
{ 46, "DictLinear", 1000000, 0, test_dict2_linear, 0}
};
int main(int argc, const char *argv[])
{
test("EMHASH", numberof(table), table, argc, argv);
exit(0);
}
+138
View File
@@ -0,0 +1,138 @@
#define NDEBUG
#include <vector>
#include <list>
#include <iterator>
#include <map>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "emilib/hash_map.hpp"
using namespace emilib;
using namespace std;
#include "common.h"
/********************************************************************************************/
static void
test_dict2(size_t n)
{
HashMap<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[rand_get()] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
HashMap<unsigned long, unsigned long>::iterator it = dict.find(rand_get());
if (it != dict.end())
s += it->second;
}
g_result = s;
}
static void
test_dict2_linear(size_t n)
{
HashMap<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[i] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
HashMap<unsigned long, unsigned long>::iterator it = dict.find(i);
if (it != dict.end())
s += it->second;
}
g_result = s;
}
/********************************************************************************************/
struct char_array_s {
char a[256];
char_array_s () { a[0] = 0 ; }
char_array_s ( const char_array_s & other) { strcpy(a, other.a); }
bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; }
};
namespace std {
template <> struct hash<char_array_s> {
std::size_t operator()(const char_array_s &k) const {
size_t hash = 0;
const char *s = k.a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
};
};
}
static void
test_dict_big(size_t n)
{
HashMap<char_array_s, char_array_s> dict;
for (size_t i = 0; i < n; i++) {
char_array_s s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_s s1;
sprintf(s1.a, "%u", rand_get());
HashMap<char_array_s, char_array_s>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
static void
test_dict_str(size_t n)
{
HashMap<string, string> dict;
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
string s2 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
HashMap<string, string>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0},
{ 46, "DictLinear", 1000000, 0, test_dict2_linear, 0}
};
int main(int argc, const char *argv[])
{
test("EMILIB", numberof(table), table, argc, argv);
exit(0);
}
+101
View File
@@ -0,0 +1,101 @@
// program to find longest contiguous subsequence
// based on https://www.geeksforgeeks.org/longest-consecutive-subsequence/
#include <iostream>
#include <unordered_set>
using namespace std;
// Returns length of the longest contiguous subsequence
int cpp_find_longest(int arr[], int n)
{
unordered_set<int> S;
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; i++)
S.insert(arr[i]);
// check each possible sequence from
// the start then update optimal length
for (int i = 0; i < n; i++) {
// if current element is the starting
// element of a sequence
if (S.find(arr[i] - 1) == S.end()) {
// Then check for next elements
// in the sequence
int j = arr[i] + 1;
while (S.find(j) != S.end())
j++;
// update optimal length if
// this length is more
ans = max(ans, j - arr[i]);
}
}
return ans;
}
#include "m-dict.h"
static inline bool oor_equal_p(int a, unsigned char c) { return a == ((c == 0) ? INT_MIN : INT_MAX); }
static inline void oor_set(int *a, unsigned char c) { *a = ((c == 0) ? INT_MIN : INT_MAX); }
DICT_OASET_DEF(dict_int, int, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)))
// Returns length of the longest contiguous subsequence
int mlib_find_longest(int arr[], int n)
{
dict_int_t S;
int ans = 0;
dict_int_init(S);
// Hash all the array elements
for (int i = 0; i < n; i++)
dict_int_push(S, arr[i]);
// check each possible sequence from
// the start then update optimal length
for (int i = 0; i < n; i++) {
// if current element is the starting
// element of a sequence
int *p = dict_int_get(S, arr[i]-1);
if (p == NULL) {
// Then check for next elements
// in the sequence
int j = arr[i] + 1;
while (dict_int_get(S, j) != NULL)
j++;
// update optimal length if
// this length is more
ans = M_MAX(ans, j - arr[i]);
}
}
dict_int_clear(S);
return ans;
}
#include "common.h"
int main(int argc, const char *argv[])
{
int n = argc == 1 ? 10000 : atoi(argv[1]);
int *arr = (int*) malloc(n * sizeof(int));
for(int i = 0; i < n; i++)
arr[i] = rand_get();
unsigned long long t0 = cputime();
cout << "Length of the Longest contiguous subsequence is "
<< cpp_find_longest(arr, n) << endl;
unsigned long long t1 = cputime();
cout << "Length of the Longest contiguous subsequence is "
<< mlib_find_longest(arr, n) << endl;
unsigned long long t2 = cputime();
cout << "Time C++: " << (t1-t0) << " Time M*LIB: " << (t2-t1) << endl;
return 0;
}
+25 -7
View File
@@ -42,6 +42,23 @@ test_dict2(size_t n)
g_result = s;
}
static void
test_dict2_linear(size_t n)
{
flat_hash_map<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[i] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
flat_hash_map<unsigned long, unsigned long>::iterator it = dict.find(i);
if (it != dict.end())
s += it->second;
}
g_result = s;
}
/********************************************************************************************/
struct char_array_s {
char a[256];
@@ -108,14 +125,15 @@ test_dict_str(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0},
{ 46, "DictLinear", 1000000, 0, test_dict2_linear, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS(u) time", 1000000, test_dict_str);
test("FLAT-HASPMAP", numberof(table), table, argc, argv);
exit(0);
}
+10 -13
View File
@@ -186,20 +186,17 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("GLIB", numberof(table), table, argc, argv);
exit(0);
}
+9 -8
View File
@@ -15,7 +15,7 @@
#include <stdbool.h>
#include <string.h>
#include "src/hopscotch_map.h"
#include "hopscotch_map.h"
using namespace tsl;
using namespace std;
@@ -109,14 +109,15 @@ test_dict_str(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS(u) time", 1000000, test_dict_str);
test("HOPSCOTCHMAP", numberof(table), table, argc, argv);
exit(0);
}
+10 -13
View File
@@ -185,21 +185,18 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]): 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("B-tree time", 1000000, test_rbtree);
if (n == 40)
test_function("DictOA time", 1000000, test_dict);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("KLIB", numberof(table), table, argc, argv);
exit(0);
}
+27 -14
View File
@@ -7,6 +7,9 @@
#include <stdint.h>
#include <unistd.h>
// Needed due to compilation error in pool.h
#include <pthread.h>
#include "dynamic.h"
#include "common.h"
@@ -45,6 +48,9 @@ static size_t hash_func (void *a)
static int equal_func(void *a, void *b)
{
const unsigned long *pa = a;
if (b == NULL) {
return *pa == -1U;
}
const unsigned long *pb = b;
return *pa == *pb;
}
@@ -52,8 +58,12 @@ static int equal_func(void *a, void *b)
static void set_func(void *a, void *b)
{
unsigned long *pa = a;
if (b == NULL) {
*pa = -1U;
} else {
const unsigned long *pb = b;
*pa = *pb;
}
}
typedef struct map_element map_element;
@@ -67,10 +77,10 @@ static void
test_dict(size_t n)
{
map dict;
map_construct(&dict, sizeof(map_element), (map_element[]) {{.key = -1}}, set_func);
map_construct(&dict, sizeof(map_element), set_func);
for (size_t i = 0; i < n; i++) {
map_insert(&dict, (map_element[]) {{.key = rand_get(), .value = rand_get()}}, hash_func, equal_func, set_func, NULL);
map_insert(&dict, (map_element[]) {{.key = rand_get(), .value = rand_get()}}, hash_func, set_func, equal_func, NULL);
}
rand_init();
unsigned int s = 0;
@@ -90,6 +100,8 @@ typedef char char_array_t[256];
static int char_equal (void *a, void *b)
{
const char_array_t *pa = (const char_array_t *)a;
if (b == NULL)
return strcmp(*pa, "") == 0;
const char_array_t *pb = (const char_array_t *)b;
return strcmp(*pa,*pb)==0;
}
@@ -103,8 +115,12 @@ static size_t char_hash(void *a)
static void char_set(void *a, void *b)
{
char_array_t *pa = (char_array_t *)a;
if (b == NULL) {
strcpy(*pa, "");
} else {
const char_array_t *pb = (const char_array_t *)b;
strcpy(*pa,*pb);
}
}
typedef struct big_map_element big_map_element;
@@ -118,16 +134,13 @@ static void
test_dict_big(size_t n)
{
map dict;
big_map_element empty;
strcpy(empty.key, "");
strcpy(empty.value, "");
map_construct(&dict, sizeof(big_map_element), &empty, char_set);
map_construct(&dict, sizeof(big_map_element), char_set);
for (size_t i = 0; i < n; i++) {
big_map_element el;
sprintf(el.key, "%u", rand_get());
sprintf(el.value, "%u", rand_get());
map_insert(&dict, &el, char_hash, char_equal, char_set, NULL);
map_insert(&dict, &el, char_hash, char_set, char_equal, NULL);
}
rand_init();
unsigned int s = 0;
@@ -144,14 +157,14 @@ test_dict_big(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 20, "Array", 100000000, 0, test_array, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 41)
test_function("Dict B time", 1000000, test_dict_big);
test("LIBDYNAMIC", numberof(table), table, argc, argv);
exit(0);
}
+10 -24
View File
@@ -6,11 +6,8 @@
#include "liblfds711.h"
#include "m-mutex.h"
#define MULTI_THREAD_MEASURE
#include "common.h"
/********************************************************************************************/
struct lfds711_queue_bmm_state g_buff;
@@ -23,12 +20,9 @@ static void final(void *arg)
unsigned long long j, s = 0;
LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
for(int i = 0; i < n;i++) {
int rv;
do {
void *p;
rv = lfds711_queue_bmm_dequeue(&g_final, &p, NULL);
while (0 == lfds711_queue_bmm_dequeue(&g_final, &p, NULL)) { m_thread_yield(); }
j = (uintptr_t)p;
} while (rv == 0);
s += j;
}
g_result = s;
@@ -42,18 +36,12 @@ static void conso(void *arg)
unsigned long long s = 0;
LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
for(int i = 0; i < n;i++) {
int rv;
do {
void *p;
rv = lfds711_queue_bmm_dequeue(&g_buff, &p, NULL);
while (0 == lfds711_queue_bmm_dequeue(&g_buff, &p, NULL)) { m_thread_yield(); }
j = (uintptr_t) p;
} while (rv == 0);
s += j;
}
int rv;
do {
rv = lfds711_queue_bmm_enqueue(&g_final, (void*)(uintptr_t)s, NULL);
} while (rv == 0);
while (0 == lfds711_queue_bmm_enqueue(&g_final, (void*)(uintptr_t)s, NULL)) { m_thread_yield(); }
}
static void prod(void *arg)
@@ -63,15 +51,12 @@ static void prod(void *arg)
size_t r = n;
LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
for(unsigned int i = 0; i < n;i++) {
int rv;
do {
rv = lfds711_queue_bmm_enqueue(&g_buff, (void*)(uintptr_t)r, NULL);
} while (rv == 0);
while (0 == lfds711_queue_bmm_enqueue(&g_buff, (void*)(uintptr_t)r, NULL)) { m_thread_yield(); }
r = r * 31421U + 6927U;
}
}
static void test_buffer(size_t n)
static void test_queue(size_t n)
{
const int cpu_count = get_cpu_count();
const int prod_count = cpu_count/2;
@@ -120,11 +105,12 @@ static void test_buffer(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 60, "Queue MPMC", 1000000, 0, test_queue, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 60)
test_function("Buffer time", 1000000, test_buffer);
test("LIBLFDS", numberof(table), table, argc, argv);
exit(0);
}
+10 -8
View File
@@ -14,8 +14,8 @@
static void test_array(size_t n)
{
sv_t *a1 = sv_alloc ( sizeof (unsigned int), 16, NULL);
sv_t *a2 = sv_alloc ( sizeof (unsigned int), 16, NULL);
srt_vector *a1 = sv_alloc ( sizeof (unsigned int), 16, NULL);
srt_vector *a2 = sv_alloc ( sizeof (unsigned int), 16, NULL);
for(size_t i = 0; i < n; i++) {
unsigned int value = rand_get();
@@ -48,7 +48,7 @@ static int cmp_float (const void *a, const void *b)
static void test_sort(size_t n)
{
sv_t *a1 = sv_alloc(sizeof(float), 16, cmp_float);
srt_vector *a1 = sv_alloc(sizeof(float), 16, cmp_float);
for(size_t i = 0; i < n; i++) {
unsigned int value = rand_get();
sv_push(&a1, &value );
@@ -60,13 +60,15 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 20, "Array", 100000000, 0, test_array, 0},
{ 50, "sort", 10000000, 0, test_sort, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("LIBSRT", numberof(table), table, argc, argv);
exit(0);
}
+387 -58
View File
@@ -8,14 +8,18 @@
#include "m-list.h"
#include "m-rbtree.h"
#include "m-bptree.h"
#include "m-deque.h"
#include "m-dict.h"
#include "m-algo.h"
#include "m-mempool.h"
#include "m-string.h"
#include "m-buffer.h"
#include "m-mutex.h"
#include "m-thread.h"
#include "m-deque.h"
#include "m-concurrent.h"
#include "m-tuple.h"
#include "m-serial-bin.h"
#include "m-serial-json.h"
#include "common.h"
@@ -40,6 +44,26 @@ static void test_array(size_t n)
/********************************************************************************************/
DEQUE_DEF(deque_uint, unsigned int)
static void test_deque(size_t n)
{
M_LET(a1, a2, DEQUE_OPLIST(deque_uint)) {
for(size_t i = 0; i < n; i++) {
deque_uint_push_back(a1, rand_get() );
deque_uint_push_back(a2, rand_get() );
}
unsigned int s = 0;
deque_uint_it_t it1, it2;
for(deque_uint_it(it1, a1), deque_uint_it(it2, a2) ; !deque_uint_end_p(it1) ; deque_uint_next(it1), deque_uint_next(it2)) {
s += *deque_uint_cref(it1 ) * *deque_uint_cref(it2 );
}
g_result = s;
}
}
/********************************************************************************************/
// Two benched mode: with or without mempool
#ifdef USE_MEMPOOL
LIST_DEF(list_uint, unsigned int, (MEMPOOL( list_mpool), MEMPOOL_LINKAGE(static)))
@@ -220,14 +244,36 @@ test_dict_oa(size_t n)
}
}
/********************************************************************************************/
static void
test_dict_oa_linear(size_t n)
{
M_LET(dict, DICT_OPLIST(dict_oa_ulong)) {
for (size_t i = 0; i < n; i++) {
dict_oa_ulong_set_at(dict, i, rand_get() );
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long *p = dict_oa_ulong_get(dict, i);
if (p)
s += *p;
}
g_result = s;
}
}
typedef char char_array_t[256];
/********************************************************************************************/
#ifndef CHAR_ARRAY_SIZE
#define CHAR_ARRAY_SIZE 256
#endif
typedef char char_array_t[CHAR_ARRAY_SIZE];
static void char_init (char_array_t a) { a[0] = 0; }
static void char_set (char_array_t a, const char_array_t b) { strcpy(a, b); }
static bool char_equal_p (const char_array_t a, const char_array_t b) { return strcmp(a,b)==0; }
static size_t char_hash(const char_array_t a) { return m_core_hash (a, strlen(a)); }
#define M_OPL_char_array_t() (INIT(char_init), INIT_SET(char_set), SET(char_set), CLEAR(char_init), HASH(char_hash), EQUAL(char_equal_p))
static bool char_oor_equal_p(const char_array_t a, unsigned char n) { return a[0] == 1+n; }
static void char_oor_set(char_array_t a, unsigned char n) { a[0] = 1+n; }
#define M_OPL_char_array_t() (INIT(char_init), INIT_SET(char_set), SET(char_set), CLEAR(char_init), HASH(char_hash), EQUAL(char_equal_p), OOR_EQUAL(char_oor_equal_p), OOR_SET(char_oor_set))
#ifdef USE_MEMPOOL
DICT_STOREHASH_DEF2(dict_char, char_array_t, M_OPEXTEND(M_OPL_char_array_t(),MEMPOOL(dict_mpool2), MEMPOOL_LINKAGE(static)), char_array_t, M_OPL_char_array_t())
@@ -235,6 +281,7 @@ DICT_STOREHASH_DEF2(dict_char, char_array_t, M_OPEXTEND(M_OPL_char_array_t(),MEM
DICT_STOREHASH_DEF2(dict_char, char_array_t, M_OPL_char_array_t(), char_array_t, M_OPL_char_array_t())
#endif
static void
test_dict_big(size_t n)
{
@@ -264,6 +311,31 @@ test_dict_big(size_t n)
#endif
}
DICT_OA_DEF2(dict_oa_char, char_array_t, char_array_t)
static void
test_dict_oa_big(size_t n)
{
M_LET(dict, DICT_OPLIST(dict_oa_char)) {
for (size_t i = 0; i < n; i++) {
char_array_t s1, s2;
sprintf(s1, "%u", rand_get());
sprintf(s2, "%u", rand_get());
dict_oa_char_set_at(dict, s1, s2);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_t s1;
sprintf(s1, "%u", rand_get());
char_array_t *p = dict_oa_char_get(dict, s1);
if (p)
s ++;
}
g_result = s;
}
}
/********************************************************************************************/
#ifdef USE_MEMPOOL
@@ -441,7 +513,7 @@ static void conso_mpmc(void *arg)
size_t n = *p_n;
unsigned long long s = 0;
for(int i = 0; i < n;i++) {
while (!queue_uint_pop(&j, g_buff_mpmc));
while (!queue_uint_pop(&j, g_buff_mpmc)) m_thread_yield();
s += j;
}
while (!queue_ull_push(g_final_mpmc, s));
@@ -453,7 +525,7 @@ static void prod_mpmc(void *arg)
size_t n = *p_n;
size_t r = n;
for(unsigned int i = 0; i < n;i++) {
while (!queue_uint_push(g_buff_mpmc, r ));
while (!queue_uint_push(g_buff_mpmc, r )) m_thread_yield();
r = r * 31421U + 6927U;
}
}
@@ -526,7 +598,7 @@ static void conso_spsc(void *arg)
size_t n = *p_n;
unsigned long long s = 0;
for(int i = 0; i < n;i++) {
while (!queue_single_uint_pop(&j, g_buff_spsc));
while (!queue_single_uint_pop(&j, g_buff_spsc)) m_thread_yield();
s += j;
}
while (!queue_single_ull_push(g_final_spsc, s));
@@ -538,7 +610,7 @@ static void prod_spsc(void *arg)
size_t n = *p_n;
size_t r = n;
for(unsigned int i = 0; i < n;i++) {
while (!queue_single_uint_push(g_buff_spsc, r ));
while (!queue_single_uint_push(g_buff_spsc, r )) m_thread_yield();
r = r * 31421U + 6927U;
}
}
@@ -581,7 +653,96 @@ static void test_queue_single(size_t n)
/********************************************************************************************/
DEQUE_DEF(deque_uint, unsigned int)
#define BULK_SIZE 20
static void final_spsc_bulk(void *arg)
{
size_t *p_n = arg;
size_t n = *p_n;
unsigned long long j, s = 0;
for(int i = 0; i < n;i++) {
while (!queue_single_ull_pop(&j, g_final_spsc)) m_thread_yield();
s += j;
}
g_result = s;
}
static void conso_spsc_bulk(void *arg)
{
size_t *p_n = arg;
size_t n = *p_n;
unsigned long long s = 0;
unsigned tab[BULK_SIZE];
for(int i = 0; i < n;i+= BULK_SIZE) {
unsigned k = queue_single_uint_pop_bulk(BULK_SIZE, tab, g_buff_spsc);
while (k != BULK_SIZE) {
m_thread_yield();
k += queue_single_uint_pop_bulk(BULK_SIZE-k, tab+k, g_buff_spsc);
}
for(k = 0; k < BULK_SIZE;k++)
s += tab[k];
}
while (!queue_single_ull_push(g_final_spsc, s));
}
static void prod_spsc_bulk(void *arg)
{
size_t *p_n = arg;
size_t n = *p_n;
if ((n % BULK_SIZE) != 0) abort();
size_t r = n;
unsigned tab[BULK_SIZE];
for(unsigned int i = 0; i < n;i+= BULK_SIZE) {
for(unsigned k = 0; k < BULK_SIZE; k++) {
tab[k] = r;
r = r * 31421U + 6927U;
}
unsigned k = queue_single_uint_push_bulk(g_buff_spsc, BULK_SIZE, tab);
while (k != BULK_SIZE) {
m_thread_yield();
k += queue_single_uint_push_bulk(g_buff_spsc, BULK_SIZE-k, tab+k);
}
}
}
static void test_queue_single_bulk(size_t n)
{
const int cpu_count = 2;
const int prod_count = cpu_count/2;
const int conso_count = cpu_count - prod_count;
// Init
queue_single_uint_init(g_buff_spsc, 64*cpu_count);
queue_single_ull_init (g_final_spsc, 64*cpu_count);
// Create thread
m_thread_t idx_p[prod_count];
m_thread_t idx_c[conso_count];
m_thread_t idx_final;
for(int i = 0; i < prod_count; i++) {
m_thread_create (idx_p[i], prod_spsc_bulk, &n);
}
for(int i = 0; i < conso_count; i++) {
m_thread_create (idx_c[i], conso_spsc_bulk, &n);
}
size_t n2 = conso_count;
m_thread_create(idx_final, final_spsc_bulk, &n2);
// Wait for jobs to be done.
for(int i = 0; i < prod_count; i++) {
m_thread_join(idx_p[i]);
}
for(int i = 0; i < conso_count; i++) {
m_thread_join(idx_c[i]);
}
m_thread_join(idx_final);
// Clear & quit
queue_single_ull_clear(g_final_spsc);
queue_single_uint_clear(g_buff_spsc);
}
/********************************************************************************************/
CONCURRENT_DEF(cdeque_uint, deque_uint_t, M_OPEXTEND(DEQUE_OPLIST(deque_uint, M_DEFAULT_OPLIST), PUSH(deque_uint_push_front)))
DEQUE_DEF(deque_ull, unsigned long long)
@@ -701,57 +862,225 @@ static void test_core_hash(size_t n)
/********************************************************************************************/
ARRAY_DEF(vector_string, string_t)
vector_string_t vstring;
vector_string_t vstring2;
static void
bench_vector_string_init(size_t n)
{
vector_string_init(vstring);
for(size_t i = 0; i < n; i++)
{
M_LET( (s, "%zu", i), string_t) {
vector_string_push_back(vstring, s);
}
}
vector_string_init(vstring2);
}
static void
bench_vector_string_init_big(size_t n)
{
vector_string_init(vstring);
for(size_t i = 0; i < n; i++)
{
M_LET( (s, "%zu%zu%zu%zu%zu%zu", i, i, i, i, i, i), string_t) {
vector_string_push_back(vstring, s);
}
}
vector_string_init(vstring2);
}
static void
bench_vector_string_bin_run(size_t n)
{
if (vector_string_size(vstring) != n) {
fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring));
abort();
}
FILE *f = fopen("tmp-serial.dat", "wb");
if (!f) abort();
M_LET( (serial, f), m_serial_bin_write_t) {
vector_string_out_serial(serial, vstring);
}
fclose(f);
f = fopen("tmp-serial.dat", "rb");
if (!f) abort();
M_LET( (serial, f), m_serial_bin_read_t) {
vector_string_in_serial(vstring2, serial);
}
fclose(f);
if (vector_string_size(vstring2) != n) {
fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring2));
abort();
}
}
static void
bench_vector_string_json_run(size_t n)
{
if (vector_string_size(vstring) != n) {
fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring));
abort();
}
FILE *f = fopen("tmp-serial.json", "wt");
if (!f) abort();
M_LET( (serial, f), m_serial_json_write_t) {
vector_string_out_serial(serial, vstring);
}
fclose(f);
f = fopen("tmp-serial.json", "rt");
if (!f) abort();
M_LET( (serial, f), m_serial_json_read_t) {
vector_string_in_serial(vstring2, serial);
}
fclose(f);
if (vector_string_size(vstring2) != n) {
fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring2));
abort();
}
}
static void
bench_vector_string_clear(void)
{
if (!vector_string_equal_p(vstring, vstring2)) {
fprintf(stderr, "ERROR: Array are different after deserialization!\n");
abort();
}
vector_string_clear(vstring);
vector_string_clear(vstring2);
}
/********************************************************************************************/
ARRAY_DEF(vector_ulong, unsigned long)
vector_ulong_t vulong;
vector_ulong_t vulong2;
static void
bench_vector_ulong_init(size_t n)
{
vector_ulong_init(vulong);
for(size_t i = 0; i < n; i++)
{
vector_ulong_push_back(vulong, i*i);
}
vector_ulong_init(vulong2);
}
static void
bench_vector_ulong_bin_run(size_t n)
{
if (vector_ulong_size(vulong) != n) {
fprintf(stderr, "ERROR: Size are different!\n");
abort();
}
FILE *f = fopen("tmp-serial.dat", "wb");
if (!f) abort();
M_LET( (serial, f), m_serial_bin_write_t) {
vector_ulong_out_serial(serial, vulong);
}
fclose(f);
f = fopen("tmp-serial.dat", "rb");
if (!f) abort();
M_LET( (serial, f), m_serial_bin_read_t) {
vector_ulong_in_serial(vulong2, serial);
}
fclose(f);
if (vector_ulong_size(vulong2) != n) {
fprintf(stderr, "ERROR: Size are different!\n");
abort();
}
}
static void
bench_vector_ulong_json_run(size_t n)
{
if (vector_ulong_size(vulong) != n) {
fprintf(stderr, "ERROR: Size are different!\n");
abort();
}
FILE *f = fopen("tmp-serial.json", "wt");
if (!f) abort();
M_LET( (serial, f), m_serial_json_write_t) {
vector_ulong_out_serial(serial, vulong);
}
fclose(f);
f = fopen("tmp-serial.json", "rt");
if (!f) abort();
M_LET( (serial, f), m_serial_json_read_t) {
vector_ulong_in_serial(vulong2, serial);
}
fclose(f);
if (vector_ulong_size(vulong2) != n) {
fprintf(stderr, "ERROR: Size are different!\n");
abort();
}
}
static void
bench_vector_ulong_clear(void)
{
if (!vector_ulong_equal_p(vulong, vulong2)) {
fprintf(stderr, "ERROR: Array are different after deserialization!\n");
abort();
}
vector_ulong_clear(vulong);
vector_ulong_clear(vulong2);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 11, "DPList", 10000000, 0, test_dlist, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 21, "Deque", 100000000, 0, test_deque, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 31, "B+tree", 1000000, 0, test_bptree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict(OA)", 1000000, 0, test_dict_oa, 0},
{ 43,"DictStr", 1000000, 0, test_dict_str, 0},
{ 46, "dictLinear(OA)", 1000000, 0, test_dict_oa_linear, 0},
{ 47, "dictBig(OA)", 1000000, 0, test_dict_oa_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
{ 51, "Stable Sort",10000000, 0, test_stable_sort, 0},
{ 60,"Buffer", 1000000, 0, test_buffer, 0},
{ 61,"Queue MPMC", 1000000, 0, test_queue, 0},
{ 62,"Buffer(P=2)", SIZE_LIMIT+1000000, 0, test_buffer, 0},
{ 63,"Queue MPMC (P=2)", SIZE_LIMIT+1000000, 0, test_queue, 0},
{ 64,"Queue SPSC (P=2)", 1000000, 0, test_queue_single, 0},
{ 65,"Queue Concurrent", 1000000, 0, test_queue_concurrent, 0},
{ 66,"Queue SPSC(Bulk)", 1000000, 0, test_queue_single_bulk, 0},
{ 70,"M_HASH", 100000000, test_hash_prepare, test_hash, test_hash_final},
{ 71,"Core Hash", 100000000, test_hash_prepare, test_core_hash, test_hash_final},
{100, "serial-bin STR", 10000000, bench_vector_string_init, bench_vector_string_bin_run, bench_vector_string_clear},
{101, "serial-bin STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_bin_run, bench_vector_string_clear},
{102, "serial-bin INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_bin_run, bench_vector_ulong_clear},
{110, "serial-json STR", 10000000, bench_vector_string_init, bench_vector_string_json_run, bench_vector_string_clear},
{111, "serial-json STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_json_run, bench_vector_string_clear},
{112, "serial-json INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_json_run, bench_vector_ulong_clear}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 11)
test_function("DPList time",10000000, test_dlist);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 31)
test_function("B+tree time", 1000000, test_bptree);
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 42)
test_function("DictOA time", 1000000, test_dict_oa);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS time", 1000000, test_dict_str);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
if (n == 51)
test_function("Stable Sort time", 10000000, test_stable_sort);
if (n == 60)
test_function("Buffer time", 1000000, test_buffer);
if (n == 61)
test_function("Queue MPMC time", 1000000, test_queue);
if (n == 62)
test_function("Buffer time (P2)", SIZE_LIMIT+1000000, test_buffer);
if (n == 63)
test_function("Queue MPMC time (P2)", SIZE_LIMIT+1000000, test_queue);
if (n == 64)
test_function("Queue SPSC time", 1000000, test_queue_single);
if (n == 65)
test_function("Queue CONCURRENT time", 1000000, test_queue_concurrent);
if (n == 70) {
n = (argc > 2) ? atoi(argv[2]) : 100000000;
test_hash_prepare(n);
test_function("M_HASH time", n, test_hash);
test_hash_final();
}
if (n == 71) {
n = (argc > 2) ? atoi(argv[2]) : 100000000;
test_hash_prepare(n);
test_function("CORE_HASH time", n, test_core_hash);
test_hash_final();
}
test("M*LIB", numberof(table), table, argc, argv);
exit(0);
}
+5 -7
View File
@@ -87,15 +87,13 @@ test_dict_noalloc(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 45, "dict(noalloc)", 1000000, 0, test_dict_noalloc, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 45)
test_function("Dict No Alloc time", 1000000, test_dict_noalloc);
test("NEDTRIES", numberof(table), table, argc, argv);
exit(0);
}
+1 -1
View File
@@ -32,7 +32,7 @@ struct Pixel
unsigned char r, g, b;
};
ARRAY_DEF(array_pixel, struct Pixel, (INIT(M_NOTHING_DEFAULT)) )
ARRAY_DEF(array_pixel, struct Pixel, (INIT(M_NOTHING_DEFAULT), INIT_SET(M_MEMCPY_DEFAULT) ))
void UseMlib(void)
{
+269
View File
@@ -0,0 +1,269 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "common.h"
/********************************************************************************************/
#define POTTERY_VECTOR_PREFIX vec_uint
#define POTTERY_VECTOR_VALUE_TYPE unsigned int
#define POTTERY_VECTOR_LIFECYCLE_BY_VALUE 1
#include "pottery/vector/pottery_vector_static.t.h"
static void test_array(size_t n)
{
vec_uint_t a1, a2;
vec_uint_init(&a1);
vec_uint_init(&a2);
for(size_t i = 0; i < n; i++) {
vec_uint_insert_last(&a1, rand_get() );
vec_uint_insert_last(&a2, rand_get() );
}
unsigned int s = 0;
for(unsigned long i = 0; i < n; i++) {
s += *vec_uint_at(&a1, i ) * *vec_uint_at(&a2, i );
}
g_result = s;
vec_uint_destroy(&a1);
vec_uint_destroy(&a2);
}
/********************************************************************************************/
typedef struct foo_s {
struct foo_s* next;
struct foo_s* previous;
int data;
} foo_t;
#define POTTERY_DOUBLY_LINKED_LIST_PREFIX foo_list
#define POTTERY_DOUBLY_LINKED_LIST_VALUE_TYPE foo_t
#include "pottery/doubly_linked_list/pottery_doubly_linked_list_static.t.h"
static void test_list(size_t n)
{
foo_list_t a1, a2;
foo_list_init(&a1);
foo_list_init(&a2);
for(size_t i = 0; i < n; i++) {
foo_t *tmp = malloc(sizeof (foo_t));
if (tmp == NULL) abort();
tmp->data = rand_get();
foo_list_link_last(&a1, tmp);
tmp = malloc(sizeof (foo_t));
if (tmp == NULL) abort();
tmp->data = rand_get();
foo_list_link_last(&a2, tmp);
}
unsigned int s = 0;
for(foo_t *it1 = foo_list_first(&a1), *it2 = foo_list_first(&a2) ;
foo_list_entry_exists(&a1, it1) ;
it1 = foo_list_next(&a1, it1), it2 = foo_list_next(&a2, it2)) {
s += it1->data * it2->data;
}
g_result = s;
for(foo_t *it1 = foo_list_first(&a1);
foo_list_entry_exists(&a1, it1) ;
) {
foo_t *tmp = it1;
it1 = foo_list_next(&a1, it1);
free(tmp);
}
for(foo_t *it1 = foo_list_first(&a2);
foo_list_entry_exists(&a2, it1) ;
) {
foo_t *tmp = it1;
it1 = foo_list_next(&a2, it1);
free(tmp);
}
}
/********************************************************************************************/
// ERROR: it returns the wrong result.
#define POTTERY_TREE_MAP_PREFIX set_ulong
#define POTTERY_TREE_MAP_VALUE_TYPE unsigned long
#define POTTERY_TREE_MAP_LIFECYCLE_MOVE_BY_VALUE 1
#define POTTERY_TREE_MAP_COMPARE_THREE_WAY(a,b) ((a) < (b) ? -1 : (a) > (b))
#define POTTERY_TREE_MAP_LIFECYCLE_DESTROY(a) (void) a
#include "pottery/tree_map/pottery_tree_map_static.t.h"
static void test_rbtree(size_t n)
{
set_ulong_t tree;
set_ulong_init(&tree);
for (size_t i = 0; i < n; i++) {
set_ulong_insert(&tree, rand_get() );
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long j = rand_get();
if (set_ulong_find(&tree, &j ) != NULL)
s += j;
}
g_result = s;
set_ulong_destroy(&tree);
}
/********************************************************************************************/
#include "m-core.h" // For M_HASH_DEFAULT
typedef struct bar_s {
unsigned long key;
unsigned long value;
} bar_t;
#define POTTERY_OPEN_HASH_MAP_PREFIX map_ulong
#define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bar_t
#define POTTERY_OPEN_HASH_MAP_KEY_TYPE unsigned long
#define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key
#define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) M_HASH_DEFAULT(x)
#define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) x == y
#define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bar_t))
#include "pottery/open_hash_map/pottery_open_hash_map_static.t.h"
static void
test_dict(size_t n)
{
map_ulong_t dict;
map_ulong_init(&dict);
for (size_t i = 0; i < n; i++) {
unsigned long value = rand_get();
unsigned long key = rand_get();
bar_t * kyle = pottery_null;
map_ulong_emplace_key(&dict, key, &kyle, pottery_null);
kyle->key = key;
kyle->value = value;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
bar_t *kyle = map_ulong_find(&dict, rand_get());
if (kyle != NULL)
s += kyle->value;
}
g_result = s;
map_ulong_destroy(&dict);
}
/********************************************************************************************/
typedef struct {
char a[256];
} char_array_t;
static inline void char_init (char_array_t *a) { a->a[0] = 0; }
static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); }
static inline bool char_equal_p (const char_array_t a, const char_array_t b) { return strcmp(a.a,b.a)==0; }
static inline void char_clear (char_array_t *a) { (void)a; }
static inline size_t char_hash(const char_array_t *a) {
size_t hash = 0;
const char *s = a->a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
}
typedef struct bars_s {
char_array_t key;
char_array_t value;
} bars_t;
#define POTTERY_OPEN_HASH_MAP_PREFIX map_achar
#define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bars_t
#define POTTERY_OPEN_HASH_MAP_KEY_TYPE char_array_t
#define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key
#define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) char_hash(&x)
#define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) char_equal_p(x, y)
#define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bars_t))
#include "pottery/open_hash_map/pottery_open_hash_map_static.t.h"
static void
test_dict_big(size_t n)
{
map_achar_t dict;
map_achar_init(&dict);
for (size_t i = 0; i < n; i++) {
char_array_t s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
bars_t * kyle = pottery_null;
map_achar_emplace_key(&dict, s1, &kyle, pottery_null);
char_set(&kyle->key, s1);
char_set(&kyle->value, s2);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_t s1;
sprintf(s1.a, "%u", rand_get());
bars_t *kyle = map_achar_find(&dict, s1);
if (kyle != NULL)
s ++;
}
g_result = s;
map_achar_destroy(&dict);
}
/********************************************************************************************/
#define POTTERY_VECTOR_PREFIX vec_float
#define POTTERY_VECTOR_VALUE_TYPE float
#define POTTERY_VECTOR_LIFECYCLE_BY_VALUE 1
#include "pottery/vector/pottery_vector_static.t.h"
#define POTTERY_INTRO_SORT_PREFIX sort_float
#define POTTERY_INTRO_SORT_VALUE_TYPE float
#define POTTERY_INTRO_SORT_LIFECYCLE_MOVE_BY_VALUE 1
#define POTTERY_INTRO_SORT_COMPARE_THREE_WAY(x, y) ( *x < *y ? -1 : *x > *y)
#include "pottery/intro_sort/pottery_intro_sort_static.t.h"
static void test_sort(size_t n)
{
vec_float_t a1;
vec_float_init(&a1);
for(size_t i = 0; i < n; i++) {
vec_float_insert_last(&a1, rand_get() );
}
sort_float(vec_float_at(&a1, 0), n);
g_result = *vec_float_at(&a1, 0);
vec_float_destroy(&a1);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
test("POTTERY", numberof(table), table, argc, argv);
exit(0);
}
+9 -7
View File
@@ -98,14 +98,16 @@ static void test_rbtree(size_t n)
/* qlibc hash functions only accept a string as the key */
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
test("QLIBC", numberof(table), table, argc, argv);
exit(0);
}
+11 -15
View File
@@ -162,22 +162,18 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict(m)", 1000000, 0, test_dict1, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict(u)", 1000000, 0, test_dict2, 0},
{ 50, "Sort",10000000, 0, test_sort, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 40)
test_function("Dict(m)time", 1000000, test_dict1);
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("QT", numberof(table), table, argc, argv);
exit(0);
}
+185
View File
@@ -0,0 +1,185 @@
#define NDEBUG
#define RAPIDJSON_HAS_STDSTRING 1
#include "rapidjson/reader.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/encodedstream.h"
#include "rapidjson/error/en.h"
#include <stdio.h>
#include <string>
#include <vector>
#include "common.h"
using namespace std;
/********************************************************************************************/
vector<string> vstring;
vector<string> vstring2;
static void
bench_vector_string_init(size_t n)
{
for(size_t i = 0; i < n; i++)
{
char buff[100];
snprintf(buff, sizeof(buff), "%zu", i);
std::string s(buff);
vstring.push_back(s);
}
}
static void
bench_vector_string_init_big(size_t n)
{
for(size_t i = 0; i < n; i++)
{
char buff[100];
snprintf(buff, sizeof(buff), "%zu%zu%zu%zu%zu%zu", i, i, i, i, i, i);
std::string s(buff);
vstring.push_back(s);
}
}
static void
bench_vector_string_json_run(size_t n)
{
if (vstring.size() != n) {
printf("Size are different!\n");
abort();
}
FILE *f = fopen("tmp-serial.json", "wt");
if (!f) abort();
{
// Prepare writer and output stream.
char writeBuffer[65536];
typedef rapidjson::AutoUTFOutputStream<unsigned, rapidjson::FileWriteStream> OutputStream;
rapidjson::FileWriteStream os(f, writeBuffer, sizeof(writeBuffer));
OutputStream eos(os, rapidjson::kUTF8, false);
rapidjson::PrettyWriter<OutputStream, rapidjson::UTF8<>, rapidjson::AutoUTF<unsigned> > writer(eos);
writer.StartArray();
for(size_t i = 0; i < n; i++){
writer.String(vstring[i]);
}
writer.EndArray();
}
fclose(f);
f = fopen("tmp-serial.json", "rt");
if (!f) abort();
{
char readBuffer[65536];
rapidjson::FileReadStream is(f, readBuffer, sizeof(readBuffer));
rapidjson::Document d;
d.ParseStream(is);
for(size_t i = 0; i < d.Size(); i++) {
rapidjson::Value& s = d[i];
vstring2.push_back(s.GetString());
}
}
fclose(f);
if (vstring2.size() != n) {
printf("Size are different!\n");
abort();
}
}
static void
bench_vector_string_clear(void)
{
if (vstring != vstring2) {
printf("Array are different!\n");
abort();
}
}
/********************************************************************************************/
vector<unsigned long> vulong;
vector<unsigned long> vulong2;
static void
bench_vector_ulong_init(size_t n)
{
for(size_t i = 0; i < n; i++)
{
vulong.push_back(i*i);
}
}
static void
bench_vector_ulong_json_run(size_t n)
{
if (vulong.size() != n) {
printf("Size are different!\n");
abort();
}
FILE *f = fopen("tmp-serial.json", "wt");
if (!f) abort();
{
// Prepare writer and output stream.
char writeBuffer[65536];
typedef rapidjson::AutoUTFOutputStream<unsigned, rapidjson::FileWriteStream> OutputStream;
rapidjson::FileWriteStream os(f, writeBuffer, sizeof(writeBuffer));
OutputStream eos(os, rapidjson::kUTF8, false);
rapidjson::PrettyWriter<OutputStream, rapidjson::UTF8<>, rapidjson::AutoUTF<unsigned> > writer(eos);
writer.StartArray();
for(size_t i = 0; i < n; i++){
writer.Int64(vulong[i]);
}
writer.EndArray();
}
fclose(f);
f = fopen("tmp-serial.json", "rt");
if (!f) abort();
{
char readBuffer[65536];
rapidjson::FileReadStream is(f, readBuffer, sizeof(readBuffer));
rapidjson::Document d;
d.ParseStream(is);
for(size_t i = 0; i < d.Size(); i++) {
rapidjson::Value& s = d[i];
vulong2.push_back(s.GetInt64());
}
}
fclose(f);
if (vulong2.size() != n) {
printf("Size are different!\n");
abort();
}
}
static void
bench_vector_ulong_clear(void)
{
if (vulong != vulong2) {
printf("Array are different!\n");
abort();
}
}
/********************************************************************************************/
const config_func_t table[] = {
{110, "serial-json STR", 10000000, bench_vector_string_init, bench_vector_string_json_run, bench_vector_string_clear},
{111, "serial-json STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_json_run, bench_vector_string_clear},
{112, "serial-json INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_json_run, bench_vector_ulong_clear}
};
int main(int argc, const char *argv[])
{
test("RAPIDJSON", numberof(table), table, argc, argv);
exit(0);
}
+159
View File
@@ -0,0 +1,159 @@
#define NDEBUG
#include <vector>
#include <list>
#include <iterator>
#include <map>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "rigtorp/HashMap.h"
using namespace rigtorp;
using namespace std;
#include "common.h"
/********************************************************************************************/
// Hash for using unsigned long as lookup key
struct UL_Hash {
size_t operator()(const unsigned long v) { return v * 7; }
};
// Equal comparison for using unsigned long as lookup key
struct UL_Equal {
bool operator()(const unsigned long lhs, const unsigned long rhs) {
return lhs == rhs;
}
};
static void
test_dict2(size_t n)
{
HashMap<unsigned long, unsigned long, UL_Hash, UL_Equal> dict(16, -1UL);
for (size_t i = 0; i < n; i++) {
dict[rand_get()] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
HashMap<unsigned long, unsigned long, UL_Hash, UL_Equal>::iterator it = dict.find(rand_get());
if (it != dict.end())
s += it->second;
}
g_result = s;
}
/********************************************************************************************/
struct char_array_s {
char a[256];
char_array_s () { a[0] = 0 ; }
char_array_s ( const char_array_s & other) { strcpy(a, other.a); }
bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; }
};
namespace std {
template <> struct hash<char_array_s> {
std::size_t operator()(const char_array_s &k) const {
size_t hash = 0;
const char *s = k.a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
};
};
}
struct BIG_Hash {
size_t operator()(const char_array_s v) { return hash<char_array_s>()(v); }
};
struct BIG_Equal {
bool operator()(const char_array_s lhs, const char_array_s rhs) {
return lhs == rhs;
}
};
static void
test_dict_big(size_t n)
{
char_array_s empty;
HashMap<char_array_s, char_array_s, BIG_Hash, BIG_Equal> dict(16, empty);
for (size_t i = 0; i < n; i++) {
char_array_s s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_s s1;
sprintf(s1.a, "%u", rand_get());
HashMap<char_array_s, char_array_s, BIG_Hash, BIG_Equal>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
struct STR_Hash {
size_t operator()(const string v) { return hash<string>()(v); }
};
struct STR_Equal {
bool operator()(const string lhs, const string rhs) {
return lhs == rhs;
}
};
static void
test_dict_str(size_t n)
{
string empty;
HashMap<string, string, STR_Hash, STR_Equal> dict(16, empty);
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
string s2 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
dict[s1] = s2;
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
HashMap<string, string, STR_Hash, STR_Equal>::iterator it = dict.find(s1);
if (it != dict.end())
s ++;
}
g_result = s;
}
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0}
};
int main(int argc, const char *argv[])
{
test("RIGTORP-HASHMAP", numberof(table), table, argc, argv);
exit(0);
}
+96
View File
@@ -0,0 +1,96 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <rigtorp/MPMCQueue.h>
#include "common.h"
/********************************************************************************************/
rigtorp::MPMCQueue<unsigned int> g_buff(4*64);
rigtorp::MPMCQueue<unsigned long long> g_final(4*64);
static void final(void *arg)
{
size_t *p_n = (size_t*) arg;
size_t n = *p_n;
unsigned long long j, s = 0;
for(unsigned int i = 0; i < n;i++) {
g_final.pop(j);
s += j;
}
g_result = s;
}
static void conso(void *arg)
{
unsigned int j;
size_t *p_n = (size_t*)arg;
size_t n = *p_n;
unsigned long long s = 0;
for(unsigned int i = 0; i < n;i++) {
g_buff.pop(j);
s += j;
}
g_final.push(s);
}
static void prod(void *arg)
{
size_t *p_n = (size_t*)arg;
size_t n = *p_n;
size_t r = n;
for(unsigned int i = 0; i < n;i++) {
g_buff.push(r);
r = r * 31421U + 6927U;
}
}
static void test_queue(size_t n)
{
const int cpu_count = get_cpu_count();
const int prod_count = cpu_count/2;
const int conso_count = cpu_count - prod_count;
if (cpu_count < 2) {
fprintf(stderr, "WARNING: Can not measure Buffer performance.\n");
return;
}
rand_get();
// Create thread
m_thread_t idx_p[prod_count];
m_thread_t idx_c[conso_count];
m_thread_t idx_final;
for(int i = 0; i < prod_count; i++) {
m_thread_create (idx_p[i], prod, &n);
}
for(int i = 0; i < conso_count; i++) {
m_thread_create (idx_c[i], conso, &n);
}
size_t n2 = conso_count;
m_thread_create(idx_final, final, &n2);
// Wait for jobs to be done.
for(int i = 0; i < prod_count; i++) {
m_thread_join(idx_p[i]);
}
for(int i = 0; i < conso_count; i++) {
m_thread_join(idx_c[i]);
}
m_thread_join(idx_final);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 60, "Queue MPMC", 1000000, 0, test_queue, 0}
};
int main(int argc, const char *argv[])
{
test("RIGTORP-MPMC-QUEUE", numberof(table), table, argc, argv);
exit(0);
}
+7 -7
View File
@@ -109,14 +109,14 @@ test_dict_str(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict", 1000000, 0, test_dict2, 0},
{ 43, "DictStr", 1000000, 0, test_dict_str, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS(u) time", 1000000, test_dict_str);
test("SPARSEPP", numberof(table), table, argc, argv);
exit(0);
}
+193
View File
@@ -0,0 +1,193 @@
#define NDEBUG
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "common.h"
/********************************************************************************************/
#define i_val unsigned int
#define i_tag uint
#include <stc/cvec.h>
static void test_array(size_t n)
{
cvec_uint a1 = cvec_uint_init(), a2 = cvec_uint_init();
for(size_t i = 0; i < n; i++) {
cvec_uint_push_back(&a1, rand_get() );
cvec_uint_push_back(&a2, rand_get() );
}
unsigned int s = 0;
for(unsigned long i = 0; i < n; i++) {
s += *cvec_uint_at(&a1, i ) * *cvec_uint_at(&a2, i );
}
g_result = s;
cvec_uint_drop(&a1);
cvec_uint_drop(&a2);
}
/********************************************************************************************/
#define i_val unsigned int
#define i_tag uint
#include <stc/clist.h>
static void test_list(size_t n)
{
clist_uint a1 = clist_uint_init(), a2 = clist_uint_init();
for(size_t i = 0; i < n; i++) {
clist_uint_push_front(&a1, rand_get() );
clist_uint_push_front(&a2, rand_get() );
}
unsigned int s = 0;
for(clist_uint_iter it1 = clist_uint_begin(&a1), it2 = clist_uint_begin(&a2) ;
it1.ref != clist_uint_end(&a1).ref ;
clist_uint_next(&it1), clist_uint_next(&it2) ) {
s += *it1.ref * *it2.ref;
}
g_result = s;
clist_uint_drop(&a1);
clist_uint_drop(&a2);
}
/********************************************************************************************/
#define i_tag ulong
#define i_key unsigned long
#include <stc/csset.h>
static void test_rbtree(size_t n)
{
csset_ulong tree = csset_ulong_init();
for (size_t i = 0; i < n; i++) {
csset_ulong_insert(&tree, rand_get() );
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unsigned long j = rand_get();
if (csset_ulong_get(&tree, j ) != NULL)
s+= j;
}
g_result = s;
csset_ulong_drop(&tree);
}
/********************************************************************************************/
#define i_tag ulong
#define i_key unsigned long
#define i_val unsigned long
#include <stc/cmap.h>
static void
test_dict(size_t n)
{
cmap_ulong dict = cmap_ulong_init();
for (size_t i = 0; i < n; i++) {
unsigned long value = rand_get();
unsigned long key = rand_get();
cmap_ulong_insert_or_assign(&dict, key, value);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
const cmap_ulong_value*val = cmap_ulong_get(&dict, rand_get());
if (val != NULL)
s += val->second;
}
g_result = s;
cmap_ulong_drop(&dict);
}
/********************************************************************************************/
typedef struct {
char a[256];
} char_array_t;
static inline void char_init (char_array_t *a) { a->a[0] = 0; }
static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); }
static inline bool char_equal_p (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a)==0; }
static inline void char_clear (char_array_t *a) { (void)a; }
static inline size_t char_hash(const char_array_t *a) {
size_t hash = 0;
const char *s = a->a;
while (*s) hash = hash * 31421 + (*s++) + 6927;
return hash;
}
#define i_tag achar
#define i_key char_array_t
#define i_val char_array_t
#define i_hash char_hash
#define i_eq char_equal_p
#include <stc/cmap.h>
static void
test_dict_big(size_t n)
{
cmap_achar dict = cmap_achar_init();
for (size_t i = 0; i < n; i++) {
char_array_t s1, s2;
sprintf(s1.a, "%u", rand_get());
sprintf(s2.a, "%u", rand_get());
cmap_achar_insert_or_assign(&dict, s1, s2);
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
char_array_t s1;
sprintf(s1.a, "%u", rand_get());
const cmap_achar_value*val = cmap_achar_get(&dict, s1);
if (val != NULL)
s ++;
}
g_result = s;
cmap_achar_drop(&dict);
}
/********************************************************************************************/
#define i_val float
#define i_tag float
#include <stc/cvec.h>
static void test_sort(size_t n)
{
cvec_float a1 = cvec_float_init();
for(size_t i = 0; i < n; i++) {
cvec_float_push_back(&a1, rand_get() );
}
cvec_float_sort(&a1);
g_result = *cvec_float_at(&a1, 0);
cvec_float_drop(&a1);
}
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
};
int main(int argc, const char *argv[])
{
test("STC", numberof(table), table, argc, argv);
exit(0);
}
+52 -21
View File
@@ -1,6 +1,7 @@
#define NDEBUG
#include <vector>
#include <deque>
#include <list>
#include <iterator>
#include <map>
@@ -53,6 +54,23 @@ static void test_array(size_t n)
/********************************************************************************************/
static void test_deque(size_t n)
{
deque<unsigned int> a1, a2;
for(size_t i = 0; i < n; i++) {
a1.push_back(rand_get() );
a2.push_back(rand_get() );
}
unsigned int s = 0;
for(auto it1 = a1.cbegin(), it2 = a2.cbegin();
it1 != a1.cend() ;it1++, it2++) {
s += *it1 * *it2;
}
g_result = s;
}
/********************************************************************************************/
static void test_rbtree(size_t n)
{
set<unsigned long> tree;
@@ -110,6 +128,24 @@ test_dict2(size_t n)
g_result = s;
}
static void
test_dict2_linear(size_t n)
{
unordered_map<unsigned long, unsigned long> dict;
for (size_t i = 0; i < n; i++) {
dict[i] = rand_get();
}
rand_init();
unsigned int s = 0;
for (size_t i = 0; i < n; i++) {
unordered_map<unsigned long, unsigned long>::iterator it = dict.find(i);
if (it != dict.end())
s += it->second;
}
g_result = s;
}
/********************************************************************************************/
struct char_array_s {
@@ -220,28 +256,23 @@ static void test_stable_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 21, "Deque", 100000000, 0, test_deque, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict(m)", 1000000, 0, test_dict1, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 42,"dict(u)", 1000000, 0, test_dict2, 0},
{ 43,"DictStr(u)", 1000000, 0, test_dict_str, 0},
{ 44,"DictStr(m)", 1000000, 0, test_dict_str2, 0},
{ 46, "dictLinear(u)", 1000000, 0, test_dict2_linear, 0},
{ 50, "Sort",10000000, 0, test_sort, 0},
{ 51, "Stable Sort",10000000, 0, test_stable_sort, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 40)
test_function("Dict(m)time", 1000000, test_dict1);
if (n == 42)
test_function("Dict(u)time", 1000000, test_dict2);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 43)
test_function("DictS(u) time", 1000000, test_dict_str);
if (n == 44)
test_function("DictS(m) time", 1000000, test_dict_str2);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
if (n == 51)
test_function("Stable Sort time", 10000000, test_stable_sort);
test("STL", numberof(table), table, argc, argv);
exit(0);
}
+323
View File
@@ -0,0 +1,323 @@
/*
* M*LIB - String Bench
*
* 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.
*/
#define NDEBUG
#include <string>
#include <sstream>
#include <string>
#include <vector>
#define M_USE_SMALL_NAME 0
#include "common.h"
#include "m-string.h"
#ifdef BENCH_CAN_USE_SDS
extern "C" {
#include "sds.h"
};
#endif
#ifdef BENCH_CAN_USE_BSTRLIB
#include "bstrlib.h"
#include "bstrwrap.h"
#include "bstraux.h"
#endif
#if defined(BENCH_CAN_USE_POTTERY)
#include "pottery/string/string.h"
#endif
/*
* BENCH
* 2000000
* 1. Generate N strings of random numbers 32 bits.
* 2. Concat all strings in a string usigned a random permutation of N.
* 3. Replace "1234" in the string into "WELL" until nothing remains.
* 4. Replace "56789" in the string into "DONE" until nothing remains.
* Return the final string length.
*/
unsigned *permutation_tab = NULL;
void random_permutation(unsigned n)
{
if (permutation_tab) free(permutation_tab);
permutation_tab = (unsigned *) malloc(n * sizeof(unsigned));
if (permutation_tab == NULL) abort();
for(unsigned i = 0; i < n; i++)
permutation_tab[i] = i;
for(unsigned i = 0; i < n; i++) {
unsigned j = rand_get() % n;
unsigned k = rand_get() % n;
unsigned l = permutation_tab[j];
permutation_tab[j] = permutation_tab[k];
permutation_tab[k] = l;
}
}
using namespace std;
static void replace_all_stl(string &str, const char pattern[], const char replace[])
{
size_t pos = 0;
do {
pos = str.find(pattern, pos);
if (pos != string::npos) {
str.replace (pos, strlen(pattern), replace);
}
} while (pos != string::npos);
}
size_t bench_stl(unsigned n)
{
vector<string> tab;
tab.resize(n);
for(unsigned i = 0; i < n; i++)
tab[i] = to_string(rand_get());
string str;
for(unsigned i = 0; i < n; i++) {
str += tab[permutation_tab[i]];
}
replace_all_stl(str, "1234", "WELL");
replace_all_stl(str, "56789", "DONE");
return str.length();
}
size_t bench_mlib(unsigned n)
{
m_string_t *tab = (m_string_t*) malloc (n * sizeof (m_string_t));
assert (tab != 0);
// P1
for(unsigned i = 0; i < n; i++) {
m_string_init(tab[i]);
m_string_set_ui(tab[i], rand_get());
}
// P2
m_string_t str;
m_string_init(str);
for(unsigned i = 0; i < n; i++) {
m_string_cat(str, tab[permutation_tab[i]]);
}
// P3
m_string_replace_all_cstr(str, "1234", "WELL");
m_string_replace_all_cstr(str, "56789", "DONE");
size_t length = m_string_size(str);
// Clean
m_string_clear(str);
for(unsigned i = 0; i < n; i++) {
m_string_clear(tab[i]);
}
free(tab);
return length;
}
#ifdef BENCH_CAN_USE_BSTRLIB
static void replace_all_bstrlib(CBString &str, const char pattern[], const char replace[])
{
size_t pos = 0;
do {
pos = str.find(pattern, pos);
if (pos != string::npos) {
str.replace (pos, strlen(pattern), replace);
}
} while (pos != string::npos);
}
size_t bench_bstrlib(unsigned n)
{
vector<CBString> tab;
tab.resize(n);
for(unsigned i = 0; i < n; i++) {
char tmp[10];
sprintf(tmp, "%u", rand_get());
tab[i] = tmp;
}
CBString str;
for(unsigned i = 0; i < n; i++) {
str += tab[permutation_tab[i]];
}
replace_all_bstrlib(str, "1234", "WELL");
replace_all_bstrlib(str, "56789", "DONE");
return str.length();
}
#endif
#ifdef BENCH_CAN_USE_SDS
sds SDS_replace_at(sds str, size_t pos, size_t len, const char str2[])
{
// simple implementation as replace is not available
sds a = sdsnewlen((const void*) str, pos);
a = sdscat(a, str2);
a = sdscat(a, &str[pos+len]);
sdsfree(str);
return a;
}
sds replace_all_sds(sds str, const char pattern[], const char replace[])
{
size_t pos = 0;
do {
char *p = strstr(&str[pos], pattern);
pos = p == NULL ? -1U : (p - str);
if (pos != -1U) {
str = SDS_replace_at(str, pos, strlen(pattern), replace);
}
} while (pos != -1U);
return str;
}
size_t bench_sds(unsigned n)
{
sds *tab = (sds*) malloc (n * sizeof (sds));
assert (tab != 0);
// P1
for(unsigned i = 0; i < n; i++) {
tab[i] = sdsfromlonglong(rand_get());
}
// P2
sds str = sdsempty();
for(unsigned i = 0; i < n; i++) {
str = sdscat(str, tab[permutation_tab[i]]);
}
// P3
str = replace_all_sds(str, "1234", "WELL");
str = replace_all_sds(str, "56789", "DONE");
// Clean
size_t length = sdslen(str);
sdsfree(str);
for(unsigned i = 0; i < n; i++) {
sdsfree(tab[i]);
}
free(tab);
return length;
}
#endif
#if defined(BENCH_CAN_USE_POTTERY)
size_t pottery_find_cstr(string_t *b, size_t index, const char *pattern)
{
// I cannot find such function in the API
const char *s = string_cstr(b);
const char *r = strstr(&s[index], pattern);
return r == NULL ? SIZE_MAX : r - s;
}
void pottery_replace_all_str(string_t *str, const char *s, const char *d)
{
size_t i = 0;
while (true) {
i = pottery_find_cstr(str, i, s);
if (i==SIZE_MAX) return;
string_remove(str, i, strlen(s));
string_insert_cstr(str, i, d);
}
}
size_t bench_pottery(unsigned n)
{
string_t *tab = (string_t*) malloc (n * sizeof (string_t));
assert (tab != 0);
// P1
for(unsigned i = 0; i < n; i++) {
string_init(&tab[i]);
string_append_format(&tab[i], "%u", rand_get());
}
// P2
string_t str;
string_init(&str);
for(unsigned i = 0; i < n; i++) {
string_append_string(&str, &tab[permutation_tab[i]]);
}
// P3
pottery_replace_all_str(&str, "1234", "WELL");
pottery_replace_all_str(&str, "56789", "DONE");
size_t length = string_length(&str);
// Clean
string_clear(&str);
for(unsigned i = 0; i < n; i++) {
string_clear(&tab[i]);
}
free(tab);
return length;
}
#endif
int main(int argc, const char *argv[])
{
unsigned length, n = atoi(argv[1]);
unsigned select = atoi(argv[2]);
const char *name;
random_permutation(n);
rand_init();
unsigned long long t0 = cputime();
switch (select) {
case 0:
length = bench_mlib(n);
name = "MLIB";
break;
case 1:
length = bench_stl(n);
name = "STL";
break;
#ifdef BENCH_CAN_USE_SDS
case 2:
length = bench_sds(n);
name = "SDS";
break;
#endif
#ifdef BENCH_CAN_USE_BSTRLIB
case 4:
length = bench_bstrlib(n);
name = "BSTRLIB";
break;
#endif
#if defined(BENCH_CAN_USE_POTTERY)
case 5:
length = bench_pottery(n);
name = "POTTERY";
break;
#endif
default:
exit(0);
}
unsigned long long t1 = cputime();
printf("%5.5s LENGTH=%u T= %f s\n", name, length, (t1-t0) / 1000000.0 );
return 0;
}
+498 -147
View File
File diff suppressed because it is too large. Load diff
+9 -11
View File
@@ -206,18 +206,16 @@ test_dict_big(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 30, "Rbtree", 1000000, 0, test_rbtree, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 30)
test_function("Rbtree time", 1000000, test_rbtree);
if (n == 40)
test_function("Dict time", 1000000, test_dict);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
test("TommyDS", numberof(table), table, argc, argv);
exit(0);
}
+10 -12
View File
@@ -1,4 +1,5 @@
#define NDEBUG
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
@@ -199,19 +200,16 @@ static void test_sort(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 10, "List", 10000000, 0, test_list, 0},
{ 20, "Array", 100000000, 0, test_array, 0},
{ 40, "dict", 1000000, 0, test_dict, 0},
{ 41, "dictBig", 1000000, 0, test_dict_big, 0},
{ 50, "sort", 10000000, 0, test_sort, 0}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]): 0;
if (n == 10)
test_function("List time",10000000, test_list);
if (n == 20)
test_function("Array time", 100000000, test_array);
if (n == 40 || n == 42)
test_function("Dict time", 1000000, test_dict);
if (n == 41)
test_function("DictB time", 1000000, test_dict_big);
if (n == 50)
test_function("Sort time", 10000000, test_sort);
test("UT-HASH", numberof(table), table, argc, argv);
exit(0);
}
+4 -9
View File
@@ -31,17 +31,12 @@ static void test_hash(size_t n)
/********************************************************************************************/
const config_func_t table[] = {
{ 70,"XXHASH64", 100000000, test_hash_prepare, test_hash, test_hash_final}
};
int main(int argc, const char *argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 0;
if (n == 70) {
n = (argc > 2) ? atoi(argv[2]) : 100000000;
test_hash_prepare(n);
test_function("XXHASH64 time", n, test_hash);
test_hash_final();
}
test("XXHASH", numberof(table), table, argc, argv);
exit(0);
}
+306
View File
@@ -0,0 +1,306 @@
/*
* M*LIB - common functions for bench module
*
* 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 <string.h>
#include "common.h"
// Maximum supported value for repeat argument
#define MAX_REPEAT 10000
// The global result
unsigned long g_result;
// The rand value
#if defined(MULTI_THREAD_MEASURE)
M_THREAD_ATTR
#endif
unsigned int randValue = 0;
void compiler_barrier(void *p)
{
// Do nothing, but let the compiler thinks that we did.
(void) p;
// Can be used for FLTO building
// asm volatile("": "+r" (p) : :"memory");
}
struct parse_opt_s {
int test_function;
double from, to, step, grow;
double within;
unsigned repeat;
bool graph, best, best_within, average, quiet;
};
static void
parse_config(struct parse_opt_s *opt, int argc, const char *argv[])
{
char *end;
opt->test_function = 0;
opt->from = 0.0;
opt->to = 0.0;
opt->step = 0.0;
opt->grow = 1.1;
opt->graph = false;
opt->best = false;
opt->best_within = false;
opt->average = false;
opt->quiet = false;
opt->repeat = 1;
opt->within = .05;
for(int i = 1; i < argc ; i++)
{
if (argv[i][0] == '-') {
if (strcmp(argv[i], "--from") == 0){
i++;
opt->from = strtod(argv[i], &end);
opt->to = opt->from;
} else if (strcmp(argv[i], "--to") == 0) {
i++;
opt->to = strtod(argv[i], &end);
opt->grow = 1.1;
} else if (strcmp(argv[i], "--step") == 0) {
i++;
opt->step = strtod(argv[i], &end);
opt->grow = 0;
} else if (strcmp(argv[i], "--grow") == 0) {
i++;
opt->grow = strtod(argv[i], &end);
opt->step = 0;
} else if (strcmp(argv[i], "--repeat") == 0) {
i++;
opt->repeat = strtol(argv[i], &end, 10);
opt->repeat = (opt->repeat > MAX_REPEAT) ? MAX_REPEAT : opt->repeat;
} else if (strcmp(argv[i], "--graph") == 0) {
opt->graph = true;
} else if (strcmp(argv[i], "--best") == 0) {
opt->best = true;
opt->average = false;
opt->best_within = false;
} else if (strcmp(argv[i], "--best-within") == 0) {
opt->best_within = true;
opt->best = false;
opt->average = false;
i++;
opt->within = strtod(argv[i], &end) / 100.0;
} else if (strcmp(argv[i], "--average") == 0) {
opt->average = true;
opt->best = false;
opt->best_within = false;
} else if (strcmp(argv[i], "--quiet") == 0) {
opt->quiet = true;
} else {
fprintf(stderr, "ERROR: Option unkown: %s.\n",
argv[i]);
exit(-1);
}
if (*end != 0) {
fprintf(stderr, "ERROR: Cannot parse %s. Expected float\n",
argv[i]);
exit(-1);
}
} else {
opt->test_function = strtol (argv[i], &end, 10);
if (*end != 0) {
fprintf(stderr, "ERROR: Cannot parse %s. Expected function number\n",
argv[i]);
exit(-1);
}
}
}
}
static int
select_config(int func, size_t n, const config_func_t functions[])
{
for(size_t i = 0; i < n;i++) {
if (functions[i].num == func)
return i;
}
fprintf(stderr, "ERROR: Function number %d not found. Available functions are:\n", func);
for(size_t i = 0; i < n;i++) {
fprintf(stderr, " %d: %s\n", functions[i].num, functions[i].funcname);
}
fprintf(stderr,
"USAGE: FUNC_NUMBER [--from number --to number (--grow number | --step number)] [--graph]\n"
"[--repeat number] [--best|--average|--best-within] [--quiet]\n");
exit(-1);
}
// Utility function for qsort
static int cmp_double(const void *pa, const void *pb)
{
const double *a = (const double *) pa, *b = (const double *)pb;
return (*a < *b) ? -1 : *a > *b;
}
/* Get the longest sequence of values within 'f'% */
static int
get_sequence(int i, int n, double tab[], double f)
{
int j;
for(j = i + 1; j < n; j++) {
if (tab[j] > f * tab[i])
break;
}
return j-i;
}
/* Return the minimum of the longest sequence of values with 'f'% */
static double
get_best_within(int n, double tab[], double f)
{
qsort(tab, n, sizeof(double), cmp_double);
int best_i = 0;
int best_seq = get_sequence(0, n, tab, f);
for(int i = 1; i < n && (n-i) > best_seq ; i++) {
int seq = get_sequence(i, n, tab, f);
if (seq > best_seq) {
best_i = i;
best_seq = seq;
}
}
return tab[best_i];
}
// Integer sqrt function (to avoid depending on libm)
static unsigned integer_sqrt(unsigned n)
{
// Find greatest shift.
int shift = 2;
unsigned nShifted = n >> shift;
// We check for nShifted being n, since some implementations
// perform shift operations modulo the word size.
while (nShifted != 0 && nShifted != n){
shift += 2;
nShifted = n >> shift;
}
shift -= 2;
// Find digits of result.
unsigned result = 0;
while (shift >= 0) {
result = result << 1;
unsigned candidateResult = result + 1;
if (candidateResult*candidateResult <= n >> shift) {
result = candidateResult;
}
shift -= 2;
}
return result;
}
void
test(const char library[], size_t n, const config_func_t functions[], int argc, const char *argv[])
{
// Init & parse arguments
// NUMBER
// --from NUMBER --to NUMBER --step NUMBER --grow NUMBER
// --graph --best --average --quiet
// --repeat N
struct parse_opt_s arg;
parse_config(&arg, argc, argv);
int i = select_config(arg.test_function, n, functions);
double from = (arg.from == 0) ? functions[i].default_n : arg.from;
double to = (arg.to == 0) ? functions[i].default_n : arg.to;
// Open plot file if needed
FILE *graph_file = NULL;
if (arg.graph) {
char filename[100];
sprintf(filename, "plot-%s-%d.dat", library, arg.test_function);
graph_file = fopen(filename, "wt");
if (!graph_file) {
fprintf(stderr, "ERROR: Cannot create the file '%s'\n", filename);
exit(-2);
}
fprintf(graph_file, "# plotting %s-%d : %s\n# N T", library, arg.test_function, functions[i].funcname);
}
// Do the bench
for(double n = from; n <= to ; n = ((arg.grow == 0) ? n + arg.step : n * arg.grow))
{
double best = (1.0/0.0);
double avg = 0.0;
double variance = 0.0;
static double measure[MAX_REPEAT];
double ba = 0.0;
if (functions[i].init != NULL)
functions[i].init(n);
// Measure the time of the test_function
for(unsigned r = 0; r < arg.repeat; r++) {
double t0 = test_function( (arg.graph|arg.best|arg.average|arg.quiet) ? NULL : functions[i].funcname, (size_t) n, functions[i].func);
best = (t0 < best) ? t0 : best;
avg += t0;
variance += t0 * t0;
measure[r] = t0;
}
// Closure of the tests
if (functions[i].clear != NULL)
functions[i].clear();
// Finish computing the different times
if (arg.repeat > 1) {
avg /= arg.repeat;
variance = (variance - arg.repeat * avg * avg) / (arg.repeat - 1);
ba = get_best_within(arg.repeat, measure, 1. + arg.within);
} else {
ba = avg;
}
// The average value shall be around best_within (and greater)
// otherwise the result doesn't seem reliable.
bool reliable = (ba <= avg && ba * (1.0+arg.within/2) + 0.5 > avg);
// Print the result
if (arg.graph) {
fprintf(graph_file, "%f %f\n", n, arg.average ? avg : arg.best ? best : ba);
} else if (arg.quiet) {
printf("%ld\n", (long)(arg.average ? avg : arg.best ? best : reliable ? ba : -1));
} else if (arg.repeat > 1) {
if (arg.average == false && arg.best_within == false)
printf ("%20.20s time %lu ms for n = %lu *** BEST ***\n", functions[i].funcname, (unsigned long) best, (unsigned long) n);
if (arg.best == false && arg.best_within == false)
printf ("%20.20s time %lu ms +/- %u ms for n = %lu *** AVERAGE ***\n", functions[i].funcname, (unsigned long) avg, 2*integer_sqrt(variance), (unsigned long) n);
if (arg.best == false && arg.average == false)
printf ("%20.20s time %lu ms for n = %lu *** BEST within %d%% *** %s\n", functions[i].funcname, (unsigned long) ba, (unsigned long) n, (int)(100*arg.within), reliable ? "" : "(unreliable result)");
}
}
// Close the FILE if needed
if (arg.graph) {
fclose(graph_file);
printf("File plot-%s-%d.dat generated.\n"
"Run in gnuplot the following command:\n"
"\tplot 'plot-%s-%d.dat' with linespoints linestyle 1\n",
library, arg.test_function, library, arg.test_function);
}
return;
}
+74 -29
View File
@@ -1,7 +1,7 @@
/*
* M*LIB - common functions for bench module
*
* Copyright (c) 2017-2018, Patrick Pelissier
* 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:
@@ -25,11 +25,40 @@
#ifndef __COMMON_BENCH__H
#define __COMMON_BENCH__H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Needed for M_THREAD_ATTR
#if defined(MULTI_THREAD_MEASURE)
#include "m-thread.h"
#endif
#if defined(_WIN32)
# include <windows.h>
#elif (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/types.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# define USE_SYSCTL
#else
# include <sys/types.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <unistd.h>
#endif
// Number of elements of a table
#define numberof(x) (sizeof(x)/sizeof(x[0]))
/* Get the current CPU time in microsecond. */
#if defined(_WIN32)
/* WINDOWS variant */
#include <windows.h>
static unsigned long long
static inline unsigned long long
cputime (void)
{
LARGE_INTEGER freq, val;
@@ -37,23 +66,18 @@ cputime (void)
QueryPerformanceCounter(&val);
return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart);
}
#else
/* UNIX variant */
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
static unsigned long long
static inline unsigned long long
cputime (void)
{
#if defined(MULTI_THREAD_MEASURE)
// Multi thread
// Multi thread: Uses real time
struct timeval tv;
gettimeofday (&tv, NULL);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
#else
// Single thread
// Single thread: Uses process usage time
struct rusage rus;
getrusage (0, &rus);
return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec;
@@ -62,44 +86,60 @@ cputime (void)
#endif
unsigned long g_result;
// The result of the bench
extern unsigned long g_result;
// The rand value
extern
#if defined(MULTI_THREAD_MEASURE)
M_THREAD_ATTR
#endif
unsigned int randValue = 0;
unsigned int randValue;
static void rand_init(void)
// Pseudo rand value generator.
// Not very random but sufficient and fast enough for the bench
static inline void rand_init(void)
{
randValue = 0;
}
static unsigned int rand_get(void)
static inline unsigned int rand_get(void)
{
randValue = randValue * 31421U + 6927U;
return randValue;
}
static void test_function(const char str[], size_t n, void (*func)(size_t))
// The function that performs the bench
static inline double
test_function(const char *str, size_t n, void (*func)(size_t))
{
double result;
unsigned long long start, end;
rand_init();
start = cputime();
(*func)(n);
end = cputime();
end = (end - start) / 1000U;
printf ("%s %lu ms for n = %lu [r=%lu]\n", str, (unsigned long) end, (unsigned long) n, g_result);
result = (double)(end-start) / 1000.0;
if (str != NULL) {
printf ("%20.20s time %.2f ms for n = %lu [r=%lu]\n", str, result, (unsigned long) n, g_result);
}
return result;
}
#if defined(_WIN32)
# include <windows.h>
#elif (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/param.h>
# include <sys/sysctl.h>
# define USE_SYSCTL
#else
# include <unistd.h>
// Configuration table
typedef struct {
int num;
const char *funcname;
size_t default_n;
void (*init)(size_t);
void (*func)(size_t);
void (*clear)(void);
} config_func_t;
// Perform a parsing of the given arguments and do the bench according to the table
#ifdef __cplusplus
extern "C"
#endif
void test(const char library[], size_t n, const config_func_t functions[], int argc, const char *argv[]);
/* Return the number of CPU of the system */
static inline int get_cpu_count(void)
@@ -123,4 +163,9 @@ static inline int get_cpu_count(void)
#endif
}
#ifdef __cplusplus
extern "C"
#endif
void compiler_barrier(void *p);
#endif
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* MLIB - TEST module
*
* Copyright (c) 2017-2018, Patrick Pelissier
* 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:
@@ -59,7 +59,7 @@ static void find_max(void)
dict_int64_set_at (dict, get_rand(), get_rand());
n++;
if ((n & ((1<<20)-1)) == 0) {
printf ("n=%lu\n", n);
printf ("n=%zu\n", n);
}
}
dict_int64_clear(dict);
+1 -2
View File
@@ -35,10 +35,9 @@ static inline size_t my_hash(uint64_t key)
{
return ((key) ^ (key)>>7);
}
static inline void update_val(uint32_t *p, uint32_t v) { *p += v;}
DICT_OA_DEF2(dict_oligonucleotide,
uint64_t, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(my_hash), OOR_EQUAL(my_oor_equal_p), OOR_SET(my_oor_set M_IPTR)),
uint32_t, M_OPEXTEND(M_DEFAULT_OPLIST, UPDATE(update_val M_IPTR)))
uint32_t, M_DEFAULT_OPLIST)
#define M_OPL_dict_oligonucleotide_t() DICT_OPLIST(dict_oligonucleotide, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(my_hash), OOR_EQUAL(my_oor_equal_p), OOR_SET(my_oor_set M_IPTR)), M_DEFAULT_OPLIST)
// Define a B*TREE-21 of uint32_t --> uint64_t and register its oplist
+2 -7
View File
@@ -1,8 +1,3 @@
#ifndef NDEBUG
#define NDEBUG
#endif
#undef NDEBUG
#include <string.h>
#include "benchmark.h"
@@ -48,7 +43,7 @@ int test_int(int N, const unsigned *data)
if (dict_int_get (h, data[i]) == NULL) {
dict_int_set_at (h, data[i], i);
} else {
dict_int_remove(h, data[i]);
dict_int_erase(h, data[i]);
}
}
ret = (int)dict_int_size(h);
@@ -64,7 +59,7 @@ int test_str(int N, char * const *data)
if (dict_str_get (h, data[i]) == NULL) {
dict_str_set_at (h, data[i], i);
} else {
dict_str_remove(h, data[i]);
dict_str_erase(h, data[i]);
}
}
ret = (int)dict_str_size(h);
+4 -4
View File
@@ -4,10 +4,10 @@
#include "m-dict.h"
#include "m-mempool.h"
DICT_DEF2(dict_int,
DICT_STOREHASH_DEF2(dict_int,
int, M_OPEXTEND(M_DEFAULT_OPLIST, MEMPOOL(mpool_int), MEMPOOL_LINKAGE(static)),
int, M_DEFAULT_OPLIST)
DICT_DEF2(dict_str,
DICT_STOREHASH_DEF2(dict_str,
const char *, M_OPEXTEND (M_CSTR_OPLIST, MEMPOOL(mpool_str), MEMPOOL_LINKAGE(static)),
int, M_DEFAULT_OPLIST)
@@ -20,7 +20,7 @@ int test_int(int N, const unsigned *data)
if (dict_int_get (h, data[i]) == NULL) {
dict_int_set_at (h, data[i], i);
} else {
dict_int_remove(h, data[i]);
dict_int_erase(h, data[i]);
}
}
ret = (int)dict_int_size(h);
@@ -38,7 +38,7 @@ int test_str(int N, char * const *data)
if (dict_str_get (h, data[i]) == NULL) {
dict_str_set_at (h, data[i], i);
} else {
dict_str_remove(h, data[i]);
dict_str_erase(h, data[i]);
}
}
ret = (int)dict_str_size(h);
+8 -5
View File
@@ -1,4 +1,5 @@
#include "../common.c"
#define M_USE_DICT_OA_PROBING(s) 1
#include "m-dict.h"
static inline bool oor_equal_p(unsigned int k, unsigned char n)
@@ -11,10 +12,10 @@ static inline void oor_set(unsigned int *k, unsigned char n)
}
DICT_OA_DEF2(dict_oa_uint,
unsigned int, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)),
unsigned int, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(hash_fn), OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)),
unsigned int, M_DEFAULT_OPLIST)
void test_int(uint32_t n, uint32_t x0)
uint32_t test_int(uint32_t n, uint32_t x0)
{
uint32_t i, x, z = 0;
dict_oa_uint_t h;
@@ -22,10 +23,12 @@ void test_int(uint32_t n, uint32_t x0)
for (i = 0, x = x0; i < n; ++i) {
x = hash32(x);
unsigned int key = get_key(n, x);
unsigned int *ptr = dict_oa_uint_get(h, key);
if (ptr) { (*ptr)++; z+= *ptr; }
else { dict_oa_uint_set_at(h, key, 1); z+=1; }
unsigned int *ptr = dict_oa_uint_get_at(h, key);
(*ptr)++;
z += *ptr;
}
fprintf(stderr, "# unique keys: %d; checksum: %u\n", (int) dict_oa_uint_size(h), z);
z = dict_oa_uint_size(h);
dict_oa_uint_clear(h);
return z;
}
+47
View File
@@ -35,3 +35,50 @@ V0.2.*: * worker_start takes a 'worker_t' as an additional parameter
The provided _remove doesn't use an iterator but a 'key', incompatible with the one of array or list.
But is like the one provided by the priority queue.
V0.3.*: * Remove B+TREE _remove method as it has been deprecated (use _erase instead)
* Remove DICT _remove method as it has been deprecated (use _erase instead)
* Make _it_to_p method of B+TREE / RB-TREE as deprecated (uses _it_until_p instead ).
* Deprecated buffer options BUFFER_BLOCKING* and BUFFER_UNBLOCKING*
as the _push_blocking and _pop_blocking functions can do the same and are more versatil.
* Iteration over the items of a dictionnary/tree returns const iterators for access through
OPLIST (impact: algorithm & M_EACH) as the IT_REF operator is no longer exported.
The _it_ref method is still defined and can be used, so you can still modify the values
but it won't be automatically used anymore (as the keys CANNOT be modified).
(Previously it generates incorrect algorithm when used with m-dict).
V0.4.*: * The order of a list initialized using M_LET is reversed
to match what is done for ARRAY (and the C++ forward_list).
* Rename M_SKIP, M_KEEP & M_MID into M_SKIP_ARGS, M_KEEP_ARGS & M_MID_ARGS
due to conflict with glibc malloc.h (that defines M_KEEP for compatibility).
* Method write_string of m_serial expects a new argument (number of characters).
* Method _init_set2 of m-i-shared is removed.
* Operator _it_insert updates it_insertion iterator to reference the inserted element.
* Dereference Type of an iterator of a dict / B+Tree is suffixed by _itref_t instead of _type_t.
* Rename TUPLE _init_set2 in _init_emplace & _set2 in _emplace.
* Rename Priority Queue method _update_further in _update.
V0.5.*: * M_INVERT is renamed into M_REVERSE to be more coherent with the REVERSE operator.
M_INVERT is marked as obsolete.
* Remove _it_to_p method of B+TREE / RB-TREE as it has been deprecated.
* Remove ALGO_INIT_VA & M_ALG0_LET_INIT_VAI of m-algo as it has been deprecated (Use of M_LET instead).
* Some Internal name of user modifiable macros have been renamed to be properly
customizable by the user.
* Rename M_HASH_SEED into M_USE_HASH_SEED (as it is a user macro).
* M_LET: for initialization of variable with arguments, if there is only one argument,
it will default to use INIT_SET instead of INIT_WITH.
==> Encapsulate the argument between () to force use of INIT_WITH.
* Remove of UPDATE operator. Use of SET for RBTREE or ADD for DICT instead.
* Make the _clean suffix for reseting the container to empty deprecated. Use new _reset suffix instead.
* Make the _get_at suffix for always getting a value deprecated. Use new _safe_get suffix instead.
* Rename CLEAN operator in RESET operator.
* Rename GET_SET_KEY operator in SAFE_GET_KEY operator.
V0.6.*: * Rename M_DEFAULT_OPLIST in M_BASIC_OPLIST
* Remove experimental macro M_IF_DEFAULT1.
* Remove M_INVERT
* String functions with _str suffix for C strings have been renamed with _cstr suffix (like string_cat_str ==> m_string_cat_cstr)
Note: the compatible layer still keeps the old naming,
so except if you are using the prefixed version of the strings
or the bounded strings API, you won't need to upgrade your code.
V0.7.*: * Rename m-mutex.h header in m-thread.h
BIN
View File
Binary file not shown.
+105 -13
View File
@@ -17,17 +17,35 @@ How to make a release?
In case of problem, open a problem report.
List of tested systems
=======================
List of automatically tested systems
====================================
* gcc 4.9, 7 & 8 on linux/x86-64
* clang 3.5, 4 & 6 on linux/x86-64
* g++ 7 & 8 on linux/x86-64
* gcc on linux/x86-64 (32 bits and 64 bits)
* g++ on linux/x86-64 (32 bits and 64 bits)
* clang on macos/x86-64
* clang++ on macos/x86-64
* tcc on linux/x86-64
* gcc 7 on windows/x86-64
* gcc 4.9 on linux/powerpc
* gcc 6 on linux/armv7l
* clang 3.8 on linux/armv7l
* gcc on windows/x86-64 (mingw)
* msvc on windows/x86-64
* clang on windows/x86-64
List of manually tested systems
===============================
* clang on linux/x86-64
* clang on linux/armv7l
* gcc on linux/powerpc
* gcc on linux/armv7l
Atomic library
==============
For the targets armel, m68k, mips, mipsel, powerpc, powerpcspe or sh4,
you may need to run the test suite by adding the atomic library:
make check LDFLAGS="-pthread -latomic"
since 'atomic' library is not automatically included for 32 bits systems.
Cross compilation
@@ -35,7 +53,7 @@ Cross compilation
There is no need to cross compile the library as it is a header only library.
However if you want to run the test with a cross-compiler, do like the following
However if you want to run the tests with a cross-compiler, do like the following
command. It performs a cross-compilation of the test suite from linux to windows
and run the test suite with wine:
@@ -47,9 +65,8 @@ Handling issues
Issues are opened in the bug tracker of the project (typically https://github.com/P-p-H-d/mlib/issues )
If the issue cannot be closed and taken into account in less than (typically) one month,
or before a release,
it shall be moved into the long term issues included in the repository:
If the issue cannot be taken into account quickly and are long term,
it should be moved into the long term issues included in the repository:
https://github.com/P-p-H-d/mlib/blob/master/doc/ISSUES.org
This is a file in ORG mode: the issues are created with the proper tags.
@@ -62,3 +79,78 @@ This will have the following gains:
Once one issue of ISSUES.org is taken into account,
its state shall be changed to DONE (the issue shall not be removed).
Debugging
=========
Debugging the library can be quite difficult
as it performs heavy preprocessing expansion
and expands all code in one line.
Different strategy for debugging the library itself are still possible:
1) Good old printf.
Add printf of interresting values in the debugged function.
2) Preprocess the library and then compile the preprocessed file like this:
cc -std=c99 -E test-file.c > test-file.i
perl -pi -e 's/;/;\n/g' test-file.i
cc -std=c99 -c -Wall test-file.i
The resulting executable can be debugged much more easily.
3) To debug the preprocessing itself, the Boot Wave library can be used
and in particular the [wave driver](https://www.boost.org/doc/libs/1_71_0/libs/wave/doc/wave_driver.html)
Add in the code the following pragmas around the code to debug:
#pragma wave trace(enable)
ARRAY_DEF (array_charp, char *)
#pragma wave trace(disable)
Run the wave driver:
./wave ex-array01.c -I .. --c99 -t test.trace
The different expansion performed by the library are described in test.trace
Coding rules
============
* Use of non standard C shall be protected under a specific compiler test,
so that the library remains compatible with a strict C99 compiler.
* C11 features shall be optional.
* Use 'make format' to format the header files properly.
* External types shall be suffixed by _t and in lower case
but shall be optional if the user doesn't want then.
* Internal types shall be suffixed by _ct and in lower case
(as confidential types)
* External / Internal functions shall be in lower case.
* External / Internal macros shall be in upper case.
* Internal macros / functions shall be prefixed by m_<container>
with container is the name of the container with one letter transformed:
o --> 0
e --> 3
i --> 1
y --> 4
This prevents the automatic completion to work when the user starts writing its function.
* Test functions shall be predicated and be suffixed by '_p'
Misc
====
To put a breakpoint for the thread sanitizer in case of error, in gdb add:
$ set env TSAN_OPTIONS=halt_on_error=1,abort_on_error=1
+509 -211
View File
@@ -1,32 +1,413 @@
*Long term issues*
------------------
==========================================================
* TODO #21: Generic Binary serialization :ENHANCEMENT:
* TODO #33 : Handling of partially constructed object :ANOMALY:
Based on issue #26 of https://github.com/P-p-H-d/mlib/issues/26
** State
Some kind of "binary serialization" on the model of get_str/parse_str
could be possible. It would be a great feature from the application
point-of-view: binary representation is more bandwidth-efficient if
used on network communications.
Support of partially constructed object needs special code to handle it
correctly (register a correct cleanup function in case of exception).
It will be good to have import/export methods to the
XML/JSON/MSGPACK/PROTOBUF/BINARY format.
However, adding all of them on by one in the M*LIB containers
doesn't seem satisfactory.
Current containers don't support such features.
Instead, adding a generic interface for the serialization of data
that may be customized by the user to perform the import/export of
objects in whatever format they want into what they want (FILE/memory/...).
To simplify it, this interface could only support one kind of import/export
per compilation unit.
** Actions
Problem:
the interface is either too high level (limiting too much what we can do)
or too low level (exporting too many internal things of the library).
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.
* TODO #20: Bucket priority queue :ENHANCEMENT:
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:
Enable support for generating an interface only for the headers
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.
This is not uniform with the others generation macros and not uniform with each other.
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.
** Plan
- Uniformization of the interface (See #31)
- Provide static size for all QUEUE.
* TODO #26 : Hash-Map for huge objects :ENHANCEMENT:
Specialize Hashmap for huge objects on supported hardware:
Based on OA hash map with taggued pointer (needs space for tagging):
low bits = high bits of hash
pointer to object { key, hash, value }
Can solve collision without dereferencing object with 1/2^lowbits chances.
NB: hash may be uneeded due to the small chances of collision.
Reduce cache usage ==> Should be faster.
Increase cache usage for very small object (integer).
Use of pointer to avoid moving object on GC.
On AMD64, only 48 bits of 64 bits are really used for addressing data.
==> lowbits= 16
Empty representation= 0 (hash can be 0. pointer cannot be it).
Deleted representation = 1 (pointer cannot be zero)
<---- PTR ----><-HASH->
#+BEGIN_SRC C
#define LOW_BITS 16
#define ALIGNED_BITS 2
void *get_ptr(int64_t x) {
return (void*) ((x >> LOW_BITS) << ALIGNED_BITS);
}
unsigned get_small_hash(int64_t x) {
return x & ((1<<LOW_BITS)-1);
}
#+END_SRC
* TODO #25 : Support of error return model for error handling. :ENHANCEMENT:
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" (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)
and throw back the error code (stopping the execution flow).
Services returning already something shall not be modified.
This model should be applied at the container level only and not globally.
Different containers may need different levels of error handling.
4 combinaison to take into account:
==> ABORT on container / ABORT on used type: The current model
==> ABORT on container / RETCODE on used type: Needs to abort on reported error.
==> RETCODE on container / ABORT on used type: Nothing particular to note.
==> RETCODE on container / RETCODE on used type: Forward retcode to caller.
Find a way to make it while not making the code too complex
(try to keep as simple as possible).
Using a specialized oplist for such containers (_OPLIST_RETCODE)
using a specialized API for retcode:
API_RET_*: that expands to
if (func(args) == 0) goto handler_exit_failure;
Adding at the end of each service:
M_END_FUNCTION(cleanup_code) that expands to different cases:
M_END_FUNCTION_VALUE(cleanup_code, return_success, return_failure) that expands to different cases:
ABORT/ABORT:
handler_exit_success:
handler_exit_failure:
return;
ABORT/RETCODE:
handler_exit_success:
return;
handler_exit_failure:
RAISE_FATAL_ERROR
RETCODE/ABORT
handler_exit_success:
return SUCESS;
handler_exit_failure:
cleanup_code
return FAILURE;
RETCODE/RETCODE
handler_exit_success:
return SUCESS;
handler_exit_failure:
cleanup_code
return FAILURE;
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? Maybe only supports those.
* 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:
** 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
a help for performance than a strict semantic usage.
** ARRAY container
The ARRAY container doesn't support strict MOVE semantic for example.
It is not a simple matter as it performs a realloc of the table, thus
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
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
other containers than the type shall be carefully moved using the provided
MOVE operator.
For example for tuple, it shall
- create an init_move operator if no one has disabled INIT_MOVE,
- export the init_move operator if at least one has exported a INIT_MOVE and no one has disabled INIT_MOVE.
** DO_INIT_MOVE operator
DO_INIT_MOVE macro is not also fully working for structure
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
to only use the default, and theses operators can be disabled or defined
only when really needed in the oplist.
However creating a default INIT_MOVE macro seems problematic.
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 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:
Add a new kind of priority queue.
See https://en.wikipedia.org/wiki/Bucket_queue
@@ -42,22 +423,20 @@ 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: 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: Ressource handler :ENHANCEMENT:
A ressouce handler which shall associated a unique handle to a ressource.
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.
It is typically a 64 bits integers always incremented (even if the program
creates one billion ressources per second, the counter won't overflow
@@ -82,175 +461,35 @@ 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: 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.
A node can be in the following state:
** First step: backoff methods :DONE:
** Second step: lock free node pool : :DONE:
Done as m-c-mempool header.
- FREE: Can be used for allocation.
- IN_USE: The node is currently used in the list.
- TO_BE_RECLAIMED: The node is semantically removed, but some others may still be used it.
** Third step: Implement generic lock free list on top of it.
So separate lists shall be used for the memory handler.
It shall also be compatible with NUMA and avoid putting all nodes in the same lists if possible:
otherwise the head will become a hot spot and slow down everything.
The ABA problem is already taken into account by the memory alloctor
provided that the lock free list doesn't try to be smart.
The ABA problem shall also be taken into account. Normaly with the provided state of the nodes,
it should not be a problem.
backoff has be used when using CAS.
backoff should also be considered when using CAS.
Concurrent insertion / insertion and insertion / deletion and deletion / deletion shall be crefully analyzed when taken into account.
Concurrent insertion / insertion and insertion / deletion and deletion / deletion shall be taken into account.
Questions:
- singly or doubly or dual push?
- needs to be logically deleted : needs a previous field
(NULL if not logically deleted) ? TBC
** First step: lock free node pool :
* DONE #14 : Memory allocation enhancement :ENHANCEMENT:
*** API based on Lock-Free Queue List
-- node_t is { node_t *next; uint ticket; data_t }
-- freelist_t : basic internal lockfree list used to construct more user friendly list (FIFO queue to avoid putting constraints on free & alloc at the same times + it is needed for reclaim part).
do not ensure consistensy of data.
is { _Atomic(node*) head, tail; }
Atomic Queue List : See algorithm by Michael & Scott on Lock Free Queue List (aka MSList)
+ freelist_push (&list, &node)
+ freelist_pop(&list) return node
+ freelist_pop_if(&list, ticket) return node Needs minor adaptation on _pop.
-- lf_memory_core_t : basic type responsible for the centralization of the list allocation.
+ init(lf_mc_t &, int max_thread, size_t alloc_size)
+ clear(lf_mc_t &)
+ lc_mc_t is {
atomic_uint ticket;
atomic_uint reg_thread; // ==> genint instead
atomic_uint tab_ticket[MAX_THREAD];
freelist_t free[MAX_THREAD];
freelist_t to_be_reclaimed[MAX_THREAD];
}
-- lf_memory_thread_t: specialization for the current thread
* lf_mt_t is { int thd_idx; lf_mc_t *global;}
* init(lf_mt_t &, &lf_mc_t g) is { thd_idx := atomic_add(&g.reg_tread, 1); .global := g; }
* clear is ??
* awake () is preparing the thread to handle operations on the list { .global.tab_ticket[.thd_idx] := atomic_add(&global.ticket, 1)+1; }
* sleep () is sleeping the thread so that it doesn't handle operations on the list and perform memory reclamation if needed {
.global.tab_ticket[.thd_idx] := UINT_MAX;
min_ticket := min(global.tab_ticket);
scan the list to_be_reclaimed while node.cpt < min_ticket,
pop the node from to_be_reclaimed and push it to the list free
lf_memory_thread_t shall be in awake state to do anything on the list.
*** Bench
Basic malloc / free: 9.6s
LF Node : 10.6s
Even if LF Node ensures a correct life cycle of the node for the read, the performance is passable.
Too much CAS:
51.40 6.13 6.13 51146587 0.00 0.00 lf_freelist_push
20.10 8.53 2.40 28143911 0.00 0.00 lf_freelist_pop
15.65 10.40 1.87 253579 0.01 0.02 lf_mempool_sleep
*** Mixed API
To overcome this limitation performs a mixed approache:
- having a simple (non atomic) list of nodes to alloc quickly the nodes.
- embedded within an atomic list of list of nodes for GC.
Thread data will be:
- FreeList is a non atomic singly linked list.
- ToBeReclaimedList is the same
- FreeListList is an atomic queue list of non atomic singly list.
- CanBeReclaimedListList is an atomic queue list of non atomic singly list
**** alloc() returns node:
- Pop from FreeList a node.
- If failure, atomic pop from FreeListList a list of list of free nodes. If success, update FreeList with the new list and pop a node from it.
- If failure, try an atomic from the FreeListList of other threads. If success, update FreeList with the new list and pop a node from it.
- If failure, malloc a new pool of FreeListList (TBD: all nodes in one pass? Needs a separate list to handle final free of nodes).
*** free(node)
- Push node in ToBeReclaimedList
*** GarbageCollector called on sleep:
- Compute min_ticket for all threads
- Atomic push of ToBeReclaimedList in CanBeReclaimedListList
- for each thread starting from mine:
-- Atomic pop from CanBeReclaimedListList[] if max ticket of pool of nodes < min_ticket and atomic push in FreeListList
max ticket of pool is the ticket of the top node of the list.
==> Should be much faster since there is much less CAS operations performed and GC is perfomed per block.
** Second step: lf_list_t is a stack based list based on RCU:
_read: classic non atomic operations.
_push(list, data, lf_mt_t) is {
allocate new node from lf_mt_t.global.free, or malloc if nothing.
copy data into node
head := atomic_load(&list.head)
do
node->next := head
while !CAS(&list.head, &head, node)
# ABA problem shall not happen since node cannot be reused immediately
_pop(list, data, lf_mt_t) is {
head := atomic_load(&list.head)
do {
if head == NULL return NULL
} while !CAS(&list.head, &head, head.next)
copy head.data into data
head.cpt := atomic_read(&global.ticket)
push node in global.to_be_reclaimed
}
_erase() TODO
_update() TODO
** Example / Way to use:
- init global memory handler.
- for each thread,
-- init thread memory handler XX,
-- ...
-- XX.awake()
-- ...
-- do as many stuff on any list as we want (this is hot spot).
-- ...
-- XX.sleep() # Memory can be reclaimed
-- XX.awake()
* TODO #15: Constructor / Destructor Prologue / Epilogue for Stack Exception Handling :ENHANCEMENT:
Constructor (and destructor) need to use user-defined prologue / epilogue.
This is in order to register the constructed object into a proper Stack Exception Handling so that exceptions throwing may work reliably.
Proposal:
- M_CONSTRUCTOR_PROLOGUE(object, oplist);
- M_CONSTRUCTOR_EPILOGUE(object, oplist);
- M_DESTRUCTOR_PROLOGUE(object, oplist);
- M_DESTRUCTOR_EPILOGUE(object, oplist);
Object creation will need to add all sub-objects into the stack, then unstack all to push instead the root object (which will recursively remove them).
See also http://freetype.sourceforge.net/david/reliable-c.html#cseh
* TODO #14: Memory allocation enhancement :ENHANCEMENT:
Enhancement of the memory allocation scheme to find way to deal properly with advance allocators:
Enhancement of the memory allocation scheme to find way to deal properly with advanced allocators:
- non-default alignment requirements for types,
- instance-based allocator (may need instance based variable access),
@@ -280,9 +519,11 @@ Needs some formal operator in the oplist to support it fully and an example.
- EXTRA_DATA: Add an extra-data field wihtin the container. Defines the type of data.
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: Atomic shared pointer :ENHANCEMENT:
* TODO #12 : New: Atomic shared pointer :ENHANCEMENT:
Add an extension to the SHARED_PTR API:
@@ -299,7 +540,10 @@ No _ref or direct _init: we need to init first a normal shared_ptr then the atom
** _atomic_set method:
It can be implemented by incrementing the non atomic shared pointer reference, then performs a compare_and_swap to the data of the atomic shared pointer, finally decrement and dec/free the swapped previous data of the atomic .
It can be implemented by incrementing the non atomic shared pointer reference,
then performs a compare_and_swap to the data of the atomic shared pointer,
finally decrement and dec/free the swapped previous data of the atomic like a normal shared pointer.
All 3 steps are safe.
** _set_atomic method:
@@ -353,13 +597,14 @@ 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: 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
The best parallel algorithm is still when there is as few synchronization as possible. A concurrent dictionary will fail at this and will result in average performance at best.
The typical best case will be in RCU context (a lot of readers, few writers), so the interface shall be compatible with such structure.
** Multiple locks within the dictionnary
A potential implementation may be to request at initialization time the number of concurrent thread N.
@@ -380,29 +625,82 @@ See also https://github.com/simonhf/sharedhashfile
** Lock Free dictionnary
Evaluate also lock-free dictionary (easier with open addressing).
It needs a complete rewrite of the inner loop through. The hard part is the dynamic resizing of the internal array (see http://preshing.com/20160222/a-resizable-concurrent-map/ for a potential solution and http://www.cs.toronto.edu/~tomhart/papers/tomhart_thesis.pdf for memory reclamation techniques). See also https://www.research.ibm.com/people/m/michael/spaa-2002.pdf
https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.2017.11.22a.pdf persents different techniques used by linux kernel.
It needs a complete rewrite of the inner loop through. The hard part is the dynamic resizing of the internal array.
Ssee http://preshing.com/20160222/a-resizable-concurrent-map/ for a potential solution
and http://www.cs.toronto.edu/~tomhart/papers/tomhart_thesis.pdf for memory reclamation techniques).
and https://www.research.ibm.com/people/m/michael/spaa-2002.pdf
https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.2017.11.22a.pdf presents different techniques used by linux kernel.
It needs before lock-free list: http://www.cse.yorku.ca/~ruppert/papers/lfll.pdf http://www.cse.yorku.ca/~ruppert/Mikhail.pdf
** Context
The best parallel algorithm is still when there is as few synchronization as possible. A concurrent dictionary will fail at this and will result in average performance at best.
The typical best case will be in RCU context (a lot of readers, few writers), so the interface shall be compatible with such structure.
** Linked list
Another solution is to create a huge list of items which is:
- atomically updated,
- in reverse order of the hash (bit 0 is highest bit, Bit 63 is the lowest bit).
Hash table will only give quick access to items to this list. Expanding the table won't change the order of the list (so the items will remain at the same place and always accessible by other threads) but just add sentinel in the sentinel at the right place (there won't be any reallocation of the list). Inserting will need to insert an item at the right place.
Not sure it will really help. To analyse.
Concurrent dictionary is possible now with CONCURRENT_DEF + DICT_DEF.
But it uses a global lock for all dictionary access.
** Open Addressing Indirect Table with a lock free node pool used as transaction pool.
A good way maybe Open Addessing table used only for indirection and a freelist memory reclamation container for handle the entries
(like a transaction).
Solution?
--------
Use of the concurrent pool (m-c-mempool) to allocate items.
The big table will only store pointers (+ part of hash in unused bits?) to such allocate items.
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:
** DONE _push_bulk
Test the capacity of the queue and push as much as possible in the queue
with one check of the atomic structure.
** DONE _pop_bulk
Test the capacity of the queue and push as much as possible in the queue
with one check of the atomic structure.
** DONE _push_force:
If the capacity of the queue is full, pop one element and push it:
push always succeed and the queue always keep the youngest element.
* DONE #21: Generic Binary serialization :ENHANCEMENT:
Based on issue #26 of https://github.com/P-p-H-d/mlib/issues/26
Some kind of "binary serialization" on the model of get_str/parse_str
could be possible. It would be a great feature from the application
point-of-view: binary representation is more bandwidth-efficient if
used on network communications.
It will be good to have import/export methods to the
XML/JSON/MSGPACK/PROTOBUF/BINARY format.
However, adding all of them on by one in the M*LIB containers
doesn't seem satisfactory.
Instead, adding a generic interface for the serialization of data
that may be customized by the user to perform the import/export of
objects in whatever format they want into what they want (FILE/memory/...).
To simplify it, this interface could only support one kind of import/export
per compilation unit.
* DONE #15: Prologue / Epilogue for Constructor / Destructor for error handling :ENHANCEMENT:
Constructor (and destructor) need to use user-defined prologue / epilogue.
This is in order to register the constructed object into a proper Exception
Handling Stack so that throwing exceptions may work reliably.
Proposal:
- M_CONSTRUCTOR_PROLOGUE(object, oplist);
- M_CONSTRUCTOR_EPILOGUE(object, oplist);
- M_DESTRUCTOR_PROLOGUE(object, oplist);
- M_DESTRUCTOR_EPILOGUE(object, oplist);
Object creation will need to add all sub-objects into the stack,
then unstack all to push instead the root object (which recursively remove them).
See also http://freetype.sourceforge.net/david/reliable-c.html#cseh
- How to handle like allocation of the object?
- How to avoid calling the destructor multiple times? (It is needed?)
- How the code can be factorized with RETCODE needs?
Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Executable
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
mkdir -p /tmp/prepro-$USER
name=/tmp/prepro-$USER/$$.c
param1=""
param2=""
while test $# -gt 0 ; do
case $1 in
-c) param2="$param2 -c" ;;
*\.c) param1="$param1 $1" ;;
*) param1="$param1 $1" ; param2="$param2 $1" ;;
esac
shift
done
cc $param1 -E |grep -v '^#' > ${name} \
&& perl -pi -e 's/\;/\;\n/g' ${name} \
&& cc $param2 ${name}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 113 KiB

BIN
View File
Binary file not shown.
+50 -5
View File
@@ -1,18 +1,63 @@
# 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.
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
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..
LDFLAGS=-pthread -lgmp
LDFLAGS=-pthread
RM=rm -f
.SUFFIXES: .c .exe
.c.exe:
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@
$(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@ `cat config` $(LDFLAGS)
all:
.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
$(RM) *.exe *.s *~ *.o ./a.dat config config.link
+68
View File
@@ -0,0 +1,68 @@
#include <stdio.h>
#include "m-array.h"
#include "m-algo.h"
/* Define a dynamic array of int */
ARRAY_DEF(vector_int, int)
/* 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. 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. We can reuse the prefix of the dynamic array */
ALGO_DEF(vector_bool, vector_bool_t)
/* ID function */
static bool id(bool x) { return x ; }
int main(void)
{
// Define, init (& later clear) myvector & tmp as vector_int_t
M_LET(myvector, tmp, vector_int_t) {
// Fill myvector with 3 int equal to 20
vector_int_fill_n(myvector, 3, 20);
// Fill tmp with 3 int equal to 33
vector_int_fill_n(tmp, 3, 33);
// Append all tmp in myvector
vector_int_splice(myvector, tmp);
// Fill tmp with 2 int equal to 10
vector_int_fill_n(tmp, 2, 10);
// Append all tmp in myvector
vector_int_splice(myvector, tmp);
// Display the result
printf("myvector contains:");
// In C11, the for loop can be simplified as :
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
ALGO_FOR_EACH(myvector, vector_int_t, M_PRINT, " ");
#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) {
vector_bool_fill_n(myvector, 3, false);
vector_bool_fill_n(tmp, 3, true);
vector_bool_splice(myvector, tmp);
vector_bool_fill_n(tmp, 2, false);
vector_bool_splice(myvector, tmp);
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;
}
+41
View File
@@ -0,0 +1,41 @@
#include "m-dict.h"
#include "m-array.h"
#include "m-algo.h"
#include "m-string.h"
/* Define a dictionnary (or hash_map or unordered_map)
* from a string_t to int */
DICT_DEF2(dict, string_t, int)
/* Register the oplist of this dictionnary globally */
#define M_OPL_dict_t() DICT_OPLIST(dict, STRING_OPLIST, M_BASIC_OPLIST)
/* Define an array of integer */
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 the key string starts with the given pattern */
#define start_with(pattern, item) \
string_start_with_str_p((item).key, (pattern))
/* Micro macro to get the value of a pair of (key, value) */
#define get_value(out, item) ((out) = (item).value)
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 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);
/* Sum theses values */
ALGO_REDUCE(s, keys, vector_int_t, sum);
printf("Sum of elements starting with 'b' is: %d\n", s);
}
return 0;
}
+41
View File
@@ -0,0 +1,41 @@
#include "m-algo.h"
#include "m-array.h"
#include "m-string.h"
/* Define an array of int */
ARRAY_DEF(vector_int, int)
/* Register the oplist of this array of int globally */
#define M_OPL_vector_int_t() ARRAY_OPLIST(vector_int)
/* Concat two strings by insertion a '-' within them */
#define str_cat(s1, s2) (string_cat_str(s1, "-"), string_cat(s1, s2))
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) {
int sum = 0, product = 0;
// Compute the sum of theses integers.
// 'add' is a registered keyword, recognized by M*LIB to perform a sum.
ALGO_REDUCE(sum, v, vector_int_t, add);
// Compute the product of theses integers.
// 'mul' is a registered keyword, recognized by M*LIB to perform a product.
ALGO_REDUCE(product, v, vector_int_t, mul);
/* Example of reduction with a transformation of the type from int to string_t
By default, the result ("s") should be of the same type as the base type
of the container. This is not the case here, we want to transform the
type. As such, we add the precision of the type 'string_t' to 's'.
The transformation from string to integer is done by string_set_si */
ALGO_REDUCE( (s, string_t), v, vector_int_t, str_cat, string_set_si);
printf ("sum: %d\n"
"product: %d\n"
"dash str: %s\n", sum, product, string_get_cstr(s));
}
return 0;
}
+629
View File
@@ -0,0 +1,629 @@
/* Include M*LIB header */
#include "m-array.h"
#include "m-string.h"
#include "m-tuple.h"
/* Provide several examples of different types usage with array,
with the oplist to use for each case.
Each time it creates and initializes an array,
fills it with some number,
computes its sum,
and returns it.
This is done for several basic C types:
- integers,
- floats,
- pointers,
- structures,
- tuples
*/
/* Generate prototypes and inline functions
for basic types.
For integer and floats, there is no need to specify
an oplist. M_BASIC_OPLIST will be used.
For bool, M_BOOL_OPLIST will be used.
*/
ARRAY_DEF(r_bool, bool)
/* Basic usage of the type */
static int
test_bool(int n)
{
r_bool_t array;
r_bool_init(array);
for(int i = 0; i < n; i++) {
r_bool_push_back(array, i & 1);
}
int s = 0;
for(int i = 0; i < n; i++) {
s += *r_bool_get(array, i);
}
r_bool_clear(array);
return s;
}
/* Same with type char */
ARRAY_DEF(r_char, char)
static int
test_char(int n)
{
r_char_t array;
r_char_init(array);
for(int i = 0; i < n; i++) {
r_char_push_back(array, i & 255);
}
int s = 0;
for(int i = 0; i < n; i++) {
s += *r_char_get(array, i);
}
r_char_clear(array);
return s;
}
/* Same with type signed int. */
ARRAY_DEF(r_int, signed int)
static int
test_int(int n)
{
r_int_t array;
r_int_init(array);
for(int i = 0; i < n; i++) {
r_int_push_back(array, i);
}
int s = 0;
for(int i = 0; i < n; i++) {
s += *r_int_get(array, i);
}
r_int_clear(array);
return s;
}
/* Same with type signed int.
But with an explicit oplist.
This generates exactly the same code than r_int
*/
ARRAY_DEF(r_int2, signed int, M_BASIC_OPLIST)
static int
test_int2(int n)
{
r_int2_t array;
r_int2_init(array);
for(int i = 0; i < n; i++) {
r_int2_push_back(array, i);
}
int s = 0;
for(int i = 0; i < n; i++) {
s += *r_int2_get(array, i);
}
r_int2_clear(array);
return s;
}
/* Same with type unsigned long long */
ARRAY_DEF(r_ullong, unsigned long long)
static int
test_ullong(int n)
{
r_ullong_t array;
r_ullong_init(array);
for(int i = 0; i < n; i++) {
r_ullong_push_back(array, i);
}
int s = 0;
for(int i = 0; i < n; i++) {
s += *r_ullong_get(array, i);
}
r_ullong_clear(array);
return s;
}
/* Same with type float */
ARRAY_DEF(r_float, float)
static int
test_float(int n)
{
r_float_t array;
r_float_init(array);
for(int i = 0; i < n; i++) {
r_float_push_back(array, i/4.0);
}
float s = 0;
for(int i = 0; i < n; i++) {
s += *r_float_get(array, i);
}
r_float_clear(array);
return s;
}
/* Same with type double and an explicit oplist*/
ARRAY_DEF(r_double, double, M_BASIC_OPLIST)
static int
test_double(int n)
{
r_double_t array;
r_double_init(array);
for(int i = 0; i < n; i++) {
r_double_push_back(array, i/4.0);
}
float s = 0;
for(int i = 0; i < n; i++) {
s += *r_double_get(array, i);
}
r_double_clear(array);
return s;
}
/* Helper function strdup */
static char *my_strdup(const char *p)
{
size_t s = strlen(p);
char *d= malloc(s+1);
if(!d) abort();
strcpy(d, p);
return d;
}
/* Same with type const char *, representing a contant C string.
We *** need *** an explicit oplist to tell M*LIB
to consider the type as a constant C string.
The oplist to use is M_CSTR_OPLIST.
We could have used M_PTR_OPLIST too,
but in this case, we won't get proper string order or
string equality.
*/
ARRAY_DEF(r_cstring, const char *, M_CSTR_OPLIST)
static int
test_cstring(int n)
{
r_cstring_t array;
r_cstring_init(array);
for(int i = 0; i < n; i++) {
char buffer[16];
// Create a string from the integer
sprintf(buffer, "%d", i);
// We need to make an explicit copy of the string
// since it is not supported by the basic type.
char *p = my_strdup(buffer);
// Push the copy in the container.
r_cstring_push_back(array, p);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get back the string
const char *p = *r_cstring_get(array, i);
// Convert it to an integer
int j = atoi(p);
s += j;
}
// We also need a special unalloc pass
// to free all constant strings we have allocated using my_strdup
for(int i = 0; i < n; i++) {
const char *p = *r_cstring_get(array, i);
free((void*)(uintptr_t)p);
}
r_cstring_clear(array);
return s;
}
/* Same with type string_t of M*LIB, representing a dynamic string.
We don't need explicit oplist to tell M*LIB!
The oplist to use is STRING_OPLIST,
but it has been registered globaly, so we don't need to explicit
give it to array_def! */
ARRAY_DEF(r_string, string_t)
static int
test_string(int n)
{
r_string_t array;
string_t str;
r_string_init(array);
string_init (str);
for(int i = 0; i < n; i++) {
// create a string from an integer
string_set_si(str, i);
// No need to make a copy in the container!
r_string_push_back(array, str);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get back the string and convert it back to an integer
int j = atoi(string_get_cstr(*r_string_get(array, i)));
s += j;
}
// No need to explicit free each term of the array
string_clear(str);
r_string_clear(array);
return s;
}
/* Same with type string_t of M*LIB, representing a variable string
and its explicit oplist. As said above, it generates exactly the
same code. */
ARRAY_DEF(r_string2, string_t, STRING_OPLIST)
/* Same with type 'volatile unsigned int *'
The array stores pointers to another integer,
allocated somewhere else.
We need to tell M*LIB to handle the basic type
as pointers without caring for what the value of
the pointer is.
So here, we **need** to specify the oplist of the type
as M_PTR_OPLIST.
*/
ARRAY_DEF(r_vintptr, volatile unsigned int *, M_PTR_OPLIST)
static int
test_vintptr(int n)
{
r_vintptr_t array;
// Allocate a secondary table to store the value.
unsigned *tab = calloc(n, sizeof(volatile unsigned int));
if (!tab) abort();
r_vintptr_init(array);
for(int i = 0; i < n; i++) {
tab[i] = i*i - i;
// Push the pointer to this integer in the array
r_vintptr_push_back(array, &tab[i]);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the integer.
// As the basic type of the container is a pointer,
// and r_vintptr_get return a pointer to the basic type
// we need to dereference its return value to get the pointer value.
volatile unsigned *p = *r_vintptr_get(array, i);
s += *p;
}
r_vintptr_clear(array);
free(tab);
return s;
}
/* Same with a structure type.
We need to tell M*LIB to handle the basic type
as POD;
So here, we **need** to specify the oplist of the type
as M_POD_OPLIST.
*/
struct rock_me_out {
int n;
float other;
};
ARRAY_DEF(r_rockme, struct rock_me_out, M_POD_OPLIST)
static int
test_rockme(int n)
{
r_rockme_t array;
r_rockme_init(array);
for(int i = 0; i < n; i++) {
struct rock_me_out rock;
rock.n = i*i - i;
rock.other = 0.0f;
// Push the struct in the array
r_rockme_push_back(array, rock);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the struct
struct rock_me_out *p = r_rockme_get(array, i);
s += p->n;
}
r_rockme_clear(array);
return s;
}
/* Same with a structure type defined with [1]:
We need to tell M*LIB to handle the basic type
as a special array;
So here, we **need** to specify the oplist of the type
as M_A1_OPLIST.
*/
typedef struct rock_me_in {
int n;
float other;
} rock_me_in[1];
ARRAY_DEF(r_rockme2, rock_me_in, M_A1_OPLIST)
static int
test_rockme2(int n)
{
r_rockme2_t array;
r_rockme2_init(array);
for(int i = 0; i < n; i++) {
rock_me_in rock;
rock->n = i*i - i;
rock->other = 0.0f;
r_rockme2_push_back(array, rock);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the struct.
rock_me_in *p = r_rockme2_get(array, i);
s += (*p)->n;
}
r_rockme2_clear(array);
return s;
}
/* Same with a structure type defined with [1] and a global registeration.
We need to tell M*LIB to handle the basic type
as a special array.
To do so, we register the oplist of rock_us_t by defining a macro based
on M_OPL_ + type name + () which expands with the oplist of the type.
Then we define the array, giving it only the type.
M*LIB will look at the global registered oplist of the type, we don't
need to give it explictly.
Global registeration makes easier code.
Registeration should be done when the type is defined.
*/
#define M_OPL_rock_me_in() M_A1_OPLIST
ARRAY_DEF(r_rockme2b, rock_me_in)
static int
test_rockme2b(int n)
{
r_rockme2b_t array;
r_rockme2b_init(array);
for(int i = 0; i < n; i++) {
rock_me_in rock;
rock->n = i*i - i;
rock->other = 0.0f;
r_rockme2b_push_back(array, rock);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the struct.
rock_me_in *p = r_rockme2b_get(array, i);
s += (*p)->n;
}
r_rockme2b_clear(array);
return s;
}
/* Same with a structure type defined as a tuple.
We first define a tuple. No need to specify the oplist as it uses basic C types
so M_BASIC_OPLIST is used by default.
Then we define the array, giving it the oplist definition of the tuple:
the macro TUPLE_OPLIST is used to build it based on the tuple name,
and the oplists of the tuple.
The main advantage of a tuple over a classic structure is that you get
free classic methods of your structure.
*/
TUPLE_DEF2(rock_you, (n, int), (other, float))
ARRAY_DEF(r_rockme3, rock_you_t, TUPLE_OPLIST(rock_you, M_BASIC_OPLIST, M_BASIC_OPLIST))
static int
test_rockme3(int n)
{
r_rockme3_t array;
rock_you_t x;
r_rockme3_init(array);
rock_you_init(x);
for(int i = 0; i < n; i++) {
rock_you_set_n(x, i*i - i);
r_rockme3_push_back(array, x);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the structure containing the integer.
rock_you_t *p = r_rockme3_get(array, i);
s += (*p)->n;
}
r_rockme3_clear(array);
rock_you_clear(x);
return s;
}
/* Same with a structure type defined as a tuple using global registeration.
We first define a tuple. No need to specify the oplist as it uses basic C types
so M_BASIC_OPLIST is used.
Then we register the oplist of rock_us_t by defining a macro based
on M_OPL_ + type name + () which expands with the oplist of the type.
Then we define the array, giving it only the type.
M*LIB will look at the global registered oplist of the type, we don't
need to give it explictly.
Global registeration makes easier code.
*/
TUPLE_DEF2(rock_us, (n, int), (other, float))
#define M_OPL_rock_us_t() TUPLE_OPLIST(rock_us, M_BASIC_OPLIST, M_BASIC_OPLIST)
ARRAY_DEF(r_rockme4, rock_us_t)
static int
test_rockme4(int n)
{
r_rockme4_t array;
rock_us_t x;
r_rockme4_init(array);
rock_us_init(x);
for(int i = 0; i < n; i++) {
rock_us_set_n(x, i*i - i);
r_rockme4_push_back(array, x);
}
int s = 0;
for(int i = 0; i < n; i++) {
// Get the pointer to the structure containing the integer.
rock_us_t *p = r_rockme4_get(array, i);
s += (*p)->n;
}
r_rockme4_clear(array);
rock_us_clear(x);
return s;
}
int main (int argc, const char *argv[])
{
int n = argc == 1 ? 10 : atoi(argv[1]);
int s;
s = test_bool(n);
printf ("S[bool] = %d\n", s);
s = test_char(n);
printf ("S[char] = %d\n", s);
s = test_int(n);
printf ("S[int] = %d\n", s);
s = test_int2(n);
printf ("S[int2] = %d\n", s);
s = test_ullong(n);
printf ("S[ullong] = %d\n", s);
s = test_float(n);
printf ("S[float] = %d\n", s);
s = test_double(n);
printf ("S[double] = %d\n", s);
s = test_cstring(n);
printf ("S[cstring] = %d\n", s);
s = test_string(n);
printf ("S[string] = %d\n", s);
s = test_vintptr(n);
printf ("S[vintptr] = %d\n", s);
s = test_rockme(n);
printf ("S[rockme] = %d\n", s);
s = test_rockme2(n);
printf ("S[rockme2] = %d\n", s);
s = test_rockme2b(n);
printf ("S[rockme2b] = %d\n", s);
s = test_rockme3(n);
printf ("S[rockme3] = %d\n", s);
s = test_rockme4(n);
printf ("S[rockme4] = %d\n", s);
exit(0);
}
+2 -2
View File
@@ -1,14 +1,14 @@
#include <stdlib.h>
#include "m-array.h"
// Let's define an array of 'int' named 'int'
// Let's define an array of 'int' named 'array_int'
ARRAY_DEF(array_int, int)
const int n = 100000;
int main(void)
{
// Declare and initilize the array
// Declare and initialize the array
array_int_t x;
array_int_init(x);
+13 -1
View File
@@ -1,9 +1,13 @@
#if HAVE_GMP
#include <gmp.h>
#include "m-array.h"
#include "m-algo.h"
/* Define an array of mpz_t */
ARRAY_DEF(array_mpz, mpz_t, M_CLASSIC_OPLIST(mpz))
/* Define some algorithm functions on array_mpz_t */
ALGO_DEF(array_mpz, ARRAY_OPLIST(array_mpz, M_CLASSIC_OPLIST(mpz)))
static inline void my_mpz_inc(mpz_t *d, const mpz_t a){
@@ -19,14 +23,22 @@ int main(void)
mpz_init_set_ui(z, 1);
array_mpz_t a;
array_mpz_init(a);
array_mpz_push_back(a, z);
for(size_t i = 2 ; i < 1000; i++) {
mpz_mul_ui(z, z, i);
array_mpz_push_back(a, z);
}
/* z = sum (a[i]^2) */
/* Compute z = sum (a[i]^2) */
array_mpz_map_reduce (&z, a, my_mpz_inc, my_mpz_sqr);
gmp_printf ("Z=%Zd\n", z);
array_mpz_clear(a);
mpz_clear(z);
}
#else
// Nothing to do
int main(void) { return 0; }
#endif
+117
View File
@@ -0,0 +1,117 @@
#include "m-array.h"
#include "m-string.h"
/* This example show how to use complex structure with array
embedding another library */
/* This is a typical trivial library with its interface */
typedef struct lib_ext_struct {
int id;
// Other data may be added
} lib_ext_struct;
/* Method to create a duplicate of the object.
The new object is heap allocated */
static lib_ext_struct *lib_ext_struct_Duplicate(const lib_ext_struct *obj)
{
lib_ext_struct *p = malloc(sizeof(lib_ext_struct));
if (!p) abort();
p->id = obj->id;
return p;
}
/* Method to delete any object */
static void lib_ext_struct_Delete(lib_ext_struct *obj)
{
free(obj);
}
/* This is the complex structure */
typedef struct {
uint32_t id;
string_t type;
lib_ext_struct* properties;
} data_node;
/* This method shall initialize the object data_node to
the init state.
It takes as first argument the object to initialize,
and since it takes by reference through a pointer,
it is compatible with 'API_2' convention for oplist */
static void data_node_init(data_node *obj)
{
obj->id = 0;
string_init(obj->type);
obj->properties = NULL;
}
/* This method shall initialize the object data_node to
the same state as the 'src' object (creating a copy, a duplicate) .
It takes as first argument the object to initialize,
and as second argument the source object.
It takes both object by reference through pointers,
as such it is compatible with 'API_6' convention for oplist */
static void data_node_init_set(data_node *obj, const data_node *src)
{
obj->id = src->id;
string_init_set(obj->type, src->type);
if (src->properties)
obj->properties = lib_ext_struct_Duplicate(src->properties);
else
obj->properties = NULL;
}
/* This method shall set the object data_node to
the same state as the 'src' object (creating a copy, a duplicate) .
THe object was already initialized.
It takes as first argument the object to initialize,
and as second argument the source object.
It takes both object by reference through pointers,
as such it is compatible with 'API_6' convention for oplist */
static void data_node_set(data_node *obj, const data_node *src)
{
obj->id = src->id;
string_set(obj->type, src->type);
if (obj->properties)
lib_ext_struct_Delete(obj->properties);
if (src->properties)
obj->properties = lib_ext_struct_Duplicate(src->properties);
else
obj->properties = NULL;
}
/* This method shall clear the object data_node to
the cleared state (aka it shall free any resource).
It takes as first argument the object to initialize,
and since it takes by reference through a pointer,
it is compatible with 'API_2' convention for oplist */
static void data_node_clear(data_node *obj)
{
string_clear(obj->type);
if (obj->properties)
lib_ext_struct_Delete(obj->properties);
}
/* Create a dynamic array of 'data_node' named array_data_node_t
and gives the minimum oplist allowing M*LIB to handle
properly the object 'data_node' with the API convention
to respect for calling the methods.
The Manual defines the different supported API.
*/
ARRAY_DEF(/* the array prefix */ array_data_node,
/* the object type */ data_node,
/* the object oplist */ (INIT(API_2(data_node_init)),
SET(API_6(data_node_set)),
INIT_SET(API_6(data_node_init_set)),
CLEAR(API_2(data_node_clear))))
/* Define a global array with the created type */
array_data_node_t global_array;
int main(void)
{
/* Call the created method */
array_data_node_init(global_array);
/* Do stuff... */
array_data_node_clear(global_array);
}
+119
View File
@@ -0,0 +1,119 @@
//
// -- An A* pathfinder inspired by the tutorial at Red Blob Games --
// https://www.redblobgames.com/pathfinding/a-star/introduction.html
// Code based on:
// https://github.com/glouw/ctl/blob/master/examples/astar.c
#include <stdio.h>
#include "m-array.h"
#include "m-string.h"
#include "m-tuple.h"
#include "m-prioqueue.h"
#include "m-dict.h"
// Create a tuple of point, but don't use its priority field for comparison.
TUPLE_DEF2( point, (x, int), (y, int), (priority, int, M_OPEXTEND( M_OPL_int(), CMP(0), HASH(0), EQUAL(0) ) ) )
#define M_OPL_point_t() TUPLE_OPLIST(point, M_OPL_int(), M_OPL_int(), M_OPL_int())
static inline int point_cmp_prio(const point_t a, const point_t b)
{
return a->priority < b->priority ? -1 : a->priority > b->priority;
}
PRIOQUEUE_DEF(prio_point, point_t, M_OPEXTEND(M_OPL_point_t(), CMP(point_cmp_prio) ) )
#define M_OPL_prio_point_t() PRIOQUEUE_OPLIST(prio_point, M_OPL_point_t() )
ARRAY_DEF(array_point, point_t)
#define M_OPL_array_point_t() ARRAY_OPLIST(array_point, M_OPL_point_t() )
DICT_DEF2(cost_point, point_t, int)
#define M_OPL_cost_point_t() DICT_OPLIST(cost_point, M_OPL_point_t(), M_OPL_int())
DICT_DEF2(step_point, point_t, point_t)
#define M_OPL_step_point_t() DICT_OPLIST(step_point, M_OPL_point_t(), M_OPL_point_t())
static inline int point_index(const point_t p, int width)
{
return p->x + width * p->y;
}
static inline void point_set_from(point_t p, const string_t maze, int width, const char pattern[])
{
size_t s = string_search_str(maze, pattern);
point_emplace(p, s % width, s / width , 0);
}
static void astar(array_point_t path, const string_t maze, int width)
{
M_LET(front, prio_point_t)
M_LET(from, step_point_t)
M_LET(costs, cost_point_t)
M_LET(start, goal, current, next, point_t)
{
point_set_from(start, maze, width, "@");
point_set_from(goal, maze, width, "!");
cost_point_set_at(costs, start, 0);
prio_point_push(front, start);
while (!prio_point_empty_p(front)) {
prio_point_pop(&current, front);
if (point_equal_p(current, goal))
break;
const struct { int x; int y; } deltas[] = {
{ -1, +1 }, { 0, +1 }, { 1, +1 },
{ -1, 0 }, /* ~ ~ */ { 1, 0 },
{ -1, -1 }, { 0, -1 }, { 1, -1 },
};
for (size_t i = 0; i < 8; i++) {
point_emplace(next, current->x + deltas[i].x, current->y + deltas[i].y, 0);
if (string_get_char(maze, point_index(next, width)) != '#') {
int *new_cost = cost_point_get(costs, current);
int *cost = cost_point_get(costs, next);
if (cost == NULL || *new_cost < *cost) {
cost_point_set_at(costs, next, *new_cost);
next->priority = *new_cost + abs(goal->x - next->x) + abs(goal->y - next->y);
prio_point_push(front, next);
step_point_set_at(from, next, current);
}
}
}
}
point_set(current, goal);
while (!point_equal_p(current, start)) {
array_point_push_back(path, current);
point_set(current, *step_point_get(from, current));
}
array_point_push_back(path, start);
}
}
int main(void)
{
M_LET( (maze,
("#########################################################################\n"
"# # # # # # #\n"
"# # ######### # ##### ######### ##### ##### ##### # ! #\n"
"# # # # # # # # # #\n"
"######### # ######### ######### ##### # # # ######### #\n"
"# # # # # # # # # # #\n"
"# # ############# # # ######### ##### # ######### # #\n"
"# # # # # # # # # #\n"
"# ############# ##### ##### # ##### ######### # ##### #\n"
"# # # # # # # # # #\n"
"# ##### ##### # ##### # ######### # # # #############\n"
"# # # # # # # # # # # #\n"
"############# # # # ######### # ##### # ##### ##### #\n"
"# # # # # # # # # #\n"
"# ##### # ######### ##### # ##### ##### ############# #\n"
"# # # # # # # # # #\n"
"# # ######### # ##### ######### # # ############# # #\n"
"# # # # # # # # # # #\n"
"# ######### # # # ##### ######### ######### # #########\n"
"# # # # # # # # # #\n"
"# @ # ##### ##### ##### ######### ##### # ######### # #\n"
"# # # # # # #\n"
"#########################################################################\n")), string_t)
M_LET(path, array_point_t)
{
int width = string_search_str(maze, "\n") + 1;
astar(path, maze, width);
for M_EACH(it, path, array_point_t) {
string_set_char(maze, point_index(*it, width), 'x');
}
printf("%s", string_get_cstr(maze));
}
}
+68
View File
@@ -0,0 +1,68 @@
#include "m-bptree.h"
#include "m-string.h"
// Define a map int -> string named map_employee_id
// The number 5 is the number of elements in a node of the B+TREE
BPTREE_DEF2(map_employee_id, 5, int, string_t)
// Register the oplist of this map globally.
#define M_OPL_map_employee_id_t() BPTREE_OPLIST2(map_employee_id, M_BASIC_OPLIST, STRING_OPLIST)
// Define a map string -> int named map_employee_name
// The number 5 is the number of elements in a node of the B+TREE
BPTREE_DEF2(map_employee_name, 5, string_t, int)
// Register the oplist of this map globally.
#define M_OPL_map_employee_name_t() BPTREE_OPLIST2(map_employee_name, STRING_OPLIST, M_BASIC_OPLIST)
int main(void)
{
map_employee_id_t Employees;
map_employee_id_init(Employees);
// Assign the map with some data
map_employee_id_set_at(Employees, 17425, STRING_CTE("Mike"));
map_employee_id_set_at(Employees, 7147, STRING_CTE("Tango"));
map_employee_id_set_at(Employees, 841, STRING_CTE("Charlie"));
map_employee_id_set_at(Employees, 11632, STRING_CTE("John Do"));
map_employee_id_set_at(Employees, 852, STRING_CTE("Peter"));
map_employee_id_set_at(Employees, 530, STRING_CTE("Amanda"));
// You can also emplace the structure
map_employee_id_emplace_val(Employees, 4258, "Elisabeth");
printf("Number of employees: %zu\n", map_employee_id_size(Employees));
// Iterate over the employee list
printf("\nList of employees (sorted by id):\n");
map_employee_id_it_t it;
for(map_employee_id_it(it, Employees); !map_employee_id_end_p(it); map_employee_id_next(it)) {
// Get a pointer to this employee from the iterator
const map_employee_id_itref_t *e = map_employee_id_cref(it);
// Print it
printf ("%d: %s\n", *(e->key_ptr), string_get_cstr(*(e->value_ptr)));
}
// Now, let's go using some macros!
// Let's create a reverse map
M_LET(Employees_r, map_employee_name_t) {
// Let's fill in the reverse map with each employee
// (using macro M_EACH)
for M_EACH(e, Employees, map_employee_id_t) {
map_employee_name_set_at(Employees_r, *(e->value_ptr), *(e->key_ptr));
}
// Iterate over the employee list
printf("\nList of employees (sorted by name):\n");
for M_EACH(e, Employees_r, map_employee_name_t) {
printf ("%d: %s\n", *(e->value_ptr), string_get_cstr(*(e->key_ptr)));
}
// Print
printf("\nElisabeth has id = %d\n", *map_employee_name_get(Employees_r, STRING_CTE("Elisabeth")));
} /* Employees_r is cleared beyond this point */
// But employee is not
map_employee_id_clear(Employees);
return 0;
}
+1 -1
View File
@@ -2,7 +2,7 @@
#include "m-buffer.h"
#include "m-shared.h"
#include "m-mutex.h"
#include "m-thread.h"
/* Global variable to stop scheduling */
atomic_bool continue_threading_g;
+41
View File
@@ -0,0 +1,41 @@
#include "m-core.h"
/* This example show how to use the M_LET_IF macro
that enables to construct an object and continue
if the construction succeeds.
*/
// Stubs defined for the example. Real code will use soundio library.
struct SoundIo { int x; };
struct SoundIoDevice { int x; };
struct SoundIoOutStream { int x; };
static struct SoundIo *soundio_create(void) { return (struct SoundIo *) malloc(sizeof(struct SoundIo)); }
static void soundio_destroy(struct SoundIo *s) { free(s); }
static struct SoundIoDevice *soundio_get_device(struct SoundIo *io, int def) { (void) io; (void) def; return (struct SoundIoDevice *) malloc(sizeof(struct SoundIoDevice)); }
static void soundio_device_unref(struct SoundIoDevice *s) { free(s); }
static struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) { (void) device ; return (struct SoundIoOutStream *) malloc(sizeof(struct SoundIoOutStream)); }
static void soundio_outstream_destroy(struct SoundIoOutStream *s) { free(s); }
static bool soundio_wait_events(struct SoundIo *s) { (void) s; return false; }
// End of stubs
int main(void)
{
int err = 1;
/* Example of using M_LET_IF macro to simplify writing error handling code.
The following code creates some object, test if the object creation succeeds, register the destructor, and print an error if something went wrong
*/
M_LET_IF( struct SoundIo *soundio = soundio_create(), soundio != 0 , soundio_destroy(soundio) , fprintf(stderr, "out of memory for soundio\n") )
M_LET_IF(struct SoundIoDevice *device = soundio_get_device(soundio, -1), device != 0, soundio_device_unref(device), fprintf(stderr, "out of memory for device\n"))
M_LET_IF(struct SoundIoOutStream *outstream = soundio_outstream_create(device), outstream != 0, soundio_outstream_destroy(outstream), fprintf(stderr, "out of memory for stream\n")) {
err = 0;
bool cont = true;
while (cont)
cont = soundio_wait_events(soundio);
}
return err;
}
+2 -2
View File
@@ -5,8 +5,8 @@
#include "m-string.h"
// Define a dictionnary of string --> int
// named 'str'
DICT_DEF2(dict_str, string_t, STRING_OPLIST, int, M_DEFAULT_OPLIST)
// named 'dict_str'
DICT_DEF2(dict_str, string_t, STRING_OPLIST, int, M_BASIC_OPLIST)
int main(void)
{
+3 -3
View File
@@ -1,10 +1,10 @@
#include "m-dict.h"
// Let's define a dictionary of 'unsigned int' --> 'char
DICT_DEF2(dict_m32, unsigned int, M_DEFAULT_OPLIST, char, M_DEFAULT_OPLIST)
DICT_DEF2(dict_m32, unsigned int, M_BASIC_OPLIST, char, M_BASIC_OPLIST)
// Let's create a synonym for its oplist.
#define M32_OPLIST DICT_OPLIST(dict_m32, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST)
#define M32_OPLIST DICT_OPLIST(dict_m32, M_BASIC_OPLIST, M_BASIC_OPLIST)
#if 1 // Non macro version.
@@ -14,7 +14,7 @@ int main(void) {
dict_m32_set_at (h, 5, 10); // h[5] = 10
char *k = dict_m32_get(h, 10); // No 10 in h, so k == NULL
int is_missing = (k != NULL); // true
assert (is_missing);
assert (is_missing); (void) is_missing;
dict_m32_erase(h, 5); // h is now empty
dict_m32_it_t it; // iterate over all dictionnary
for (dict_m32_it (it, h) ; !dict_m32_end_p (it); dict_m32_next(it)) {
+4 -3
View File
@@ -5,7 +5,8 @@
#include "m-dict.h"
#include "m-string.h"
DICT_DEF2(dict_map, char, M_DEFAULT_OPLIST, int, M_DEFAULT_OPLIST)
// Define a dictionary (hashmap) from 'char' to 'int'
DICT_DEF2(dict_map, char, int)
int main(void)
{
@@ -81,7 +82,7 @@ int main(void)
}
break;
case 7:
case 6:
dict_map_clear(mp);
string_clear (str);
exit(0);
@@ -89,7 +90,7 @@ int main(void)
default:
printf("Wrong Choice\n");
break;
}
}
}
+10 -1
View File
@@ -5,14 +5,23 @@
/* program that reads text from standard-input,
and prints the total number of distinct words found in the text.
*/
/* Definition of a set (hashset) of unique string_t */
DICT_SET_DEF(dict_str, string_t, STRING_OPLIST)
int main(void)
{
// Define word as a string_t
M_LET(word, STRING_OPLIST)
// Define wordcount as a set of string_t
M_LET(wordcount, DICT_SET_OPLIST(dict_str, STRING_OPLIST)) {
while (string_fget_word(word, " \t\n,.!;:?", stdin))
// Read a word from the standard input
while (string_fget_word(word, " \t\n,.!;:?", stdin)) {
// Push this word in the set.
// Do nothing if it already exists.
dict_str_push(wordcount, word);
}
// Print the number of words of the standard input.
printf ("Words: %zu\n", dict_str_size(wordcount));
}
}
+56
View File
@@ -0,0 +1,56 @@
#include <stdio.h>
#include "m-dict.h"
/*
* Provide OOR methods for OA Hashmap.
* See documentation for definition of OOR
* OOR values are represented as:
* empty (0) is INT_MIN
* deleted (1) is INT_MIN + 1
* So valid range for integers are [INT_MIN+2, INT_MAX]
*/
static inline bool oor_equal_p(int k, char n)
{
return k == INT_MIN + n;
}
static inline int oor_set(char n)
{
return INT_MIN + n;
}
/*
* Provide a custom hash function (optional for OA)
*/
static inline size_t hash(int n)
{
return (size_t) n; // Identity hash!
}
/* Define an OA dictionnay which performs a hashmap between an int to an int */
DICT_OA_DEF2(dict_oa,
int, M_OPEXTEND(M_BASIC_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(API_4(oor_set)), HASH(hash)),
int, M_BASIC_OPLIST)
int main(void)
{
dict_oa_t d;
dict_oa_init(d);
for(int i = 0; i < 10; i++) {
dict_oa_set_at(d, i*i, 4*i);
}
dict_oa_set_at(d, 3, -17);
printf("DICT[3] = %d\n", *dict_oa_get(d, 3));
dict_oa_it_t it;
printf("DICT=");
for(dict_oa_it(it, d); !dict_oa_end_p(it); dict_oa_next(it)) {
printf("%d:%d, ", dict_oa_cref(it)->key, dict_oa_cref(it)->value);
}
printf("\n");
dict_oa_clear(d);
return 0;
}
+64
View File
@@ -0,0 +1,64 @@
#include <stdio.h>
#include "m-dict.h"
/*
* Provide OOR methods for OA Hashmap.
* See documentation for definition of OOR
* OOR values are represented as:
* empty (0) is "EMPTY"
* deleted (1) is "DELETED"
*/
static const char empty_str[] = "EMPTY";
static const char deleted_str[] = "DELETED";
static const char *oor_table[] = { empty_str, deleted_str };
static inline bool oor_equal_p(const char *k, int n)
{
return k == oor_table[n];
}
static inline const char *oor_set(int n)
{
return oor_table[n];
}
/*
* Provide a custom hash function (optional for OA)
*/
static inline size_t hash(const char *k)
{
size_t r = 17;
while (*k) {
r = *k * 33 + r;
k++;
}
return r;
}
/* Define an OA dictionnay which performs a hashmap between a CSTR to an int */
DICT_OA_DEF2(dict_oa,
const char *, M_OPEXTEND(M_CSTR_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(API_4(oor_set)), HASH(hash)),
int, M_BASIC_OPLIST)
int main(void)
{
dict_oa_t d;
dict_oa_init(d);
dict_oa_set_at(d, "THIS", -17);
dict_oa_set_at(d, "IS", -170);
dict_oa_set_at(d, "AN", 7);
dict_oa_set_at(d, "EXAMPLE", 77);
printf("DICT[\"AN\"] = %d\n", *dict_oa_get(d, "AN"));
dict_oa_it_t it;
printf("DICT=");
for(dict_oa_it(it, d); !dict_oa_end_p(it); dict_oa_next(it)) {
printf("%s:%d, ", dict_oa_cref(it)->key, dict_oa_cref(it)->value);
}
printf("\n");
dict_oa_clear(d);
return 0;
}
+30 -6
View File
@@ -3,30 +3,54 @@
#include "m-array.h"
#include "m-dict.h"
// Define an array of size_t
ARRAY_DEF(array_size, size_t)
// Register the oplist of this array globaly
#define M_OPL_array_size_t() ARRAY_OPLIST(array_size)
// Define a dictionary (hashmap) of string_t to array of size_t
DICT_DEF2(map_pos, string_t, array_size_t)
// Register the oplist of this dictionary (hashmap)
#define M_OPL_map_pos_t() DICT_OPLIST(map_pos, STRING_OPLIST, ARRAY_OPLIST(array_size))
int main(int argc, const char *argv[])
{
if (argc == 2) {
if (argc != 2) {
printf("USAGE: %s filename\n", argv[0]);
exit(0);
}
// Define word as a string_t
M_LET(word, string_t)
// Define positions as a map of string_t-->array of size_t
M_LET(positions, map_pos_t) {
// Open the file
FILE *f = fopen(argv[1], "rt");
if (!f) return 1;
if (!f) {
fprintf(stderr, "ERROR: Cannot open %s.\n", argv[1]);
return 1;
}
// While it reads some word from the file
while (string_fget_word(word, " \t\n\r\"(),=", f)) {
array_size_t *array = map_pos_get_at(positions, word);
// Get the reference to the array of this word in the dictionnary (or create it if needed)
array_size_t *array = map_pos_safe_get(positions, word);
// Push the new offset to this word in the associated array
array_size_push_back(*array, (size_t)ftell(f) - string_size(word));
}
// Close the file
fclose(f);
// Print the words and where they are:
for M_EACH(pair, positions, map_pos_t) {
string_fputs(stdout, pair->key);
for M_EACH(pos, pair->value, array_size_t)
for M_EACH(pos, pair->value, array_size_t) {
printf(" %zu", *pos);
}
printf("\n");
}
}
}
} // All created objects are destroyed beyond this point
return 0;
}
+58 -22
View File
@@ -8,43 +8,54 @@
#include "m-string.h"
#include "m-algo.h"
// Let's create a list of 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
// 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.
ALGO_DEF(astring, M_OPL_list_string_t())
// We reuse the prefix of the list to simplify usage, but algorithms can use separate namespace.
ALGO_DEF(list_string, M_OPL_list_string_t())
int main(void)
{
// Let's create a variable named 'grow' which is a list of string_t
// Let's create a variable named 'list' which is a list of string_t
// This variable is only defined within the associated '{' '}' block.
// The constructor/destructor of the variable will be called within this block
// You can also define the variable (list_string_t) and use explicitly
// its constructor (list_string_init) / destructor (list_string_clear).
M_LET (grow, list_string_t)
M_LET (list, list_string_t)
M_LET (tmpstr, string_t) { // And let's create also a string_t
// add string elements to the list
list_string_push_back (grow, STRING_CTE("AB"));
// add string elements to the list in different ways
// First is pushing a const string.
// The macro STRING_CTE creates a const string_t based on the given const char * string.
list_string_push_back (list, STRING_CTE("AB"));
// Second is creating a separate string_t and then pushing it in the list
string_printf(tmpstr, "%d", 12);
list_string_push_back (grow, tmpstr);
list_string_push_back (grow, STRING_CTE("CD"));
list_string_push_back (list, tmpstr);
// Third is to emplace directly in the list by constructing a new string_t based on the given const char *
list_string_emplace_back (list, "CD");
// Serialize the list of string into a big string.
list_string_get_str (tmpstr, grow, false);
list_string_get_str (tmpstr, list, false);
// print out
printf("Number of elements = %zu\n", list_string_size(grow));
// print it
printf("Number of elements = %zu\n", list_string_size(list));
printf("Final string = %s\n", string_get_cstr(tmpstr));
// Let's iterate over each element of the list
// using the macro for iteration over a container.
printf ("Using macro EACH :\n");
for M_EACH (item, grow, list_string_t) {
printf ("Using macro EACH:\n");
for M_EACH (item, list, list_string_t) {
printf ("Item = ");
string_fputs (stdout, *item);
printf ("\n");
@@ -52,34 +63,59 @@ int main(void)
// You can also use classic iterator:
list_string_it_t it;
printf ("Using iterators :\n");
for(list_string_it(it, grow) ; !list_string_end_p(it) ; list_string_next(it)) {
printf ("Using iterators:\n");
for(list_string_it(it, list) ; !list_string_end_p(it) ; list_string_next(it)) {
const string_t *item = list_string_cref (it);
printf ("Item = ");
string_fputs (stdout, *item);
printf ("\n");
}
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
// Another way: we map each element to the M_PRINT function.
printf ("Using macro ALGO_FOR_EACH:");
ALGO_FOR_EACH(list, list_string_t, M_PRINT, "\nItem = ");
printf ("\n");
#endif
// Get the min and the max of the list
string_t *p = astring_min(grow);
string_t *p = list_string_min(list);
printf ("Min string is %s\n", string_get_cstr(*p));
p = astring_max(grow);
p = list_string_max(list);
printf ("Max string is %s\n", string_get_cstr(*p));
// We can even sort the list.
astring_sort(grow);
for M_EACH (item, grow, list_string_t) {
list_string_sort(list);
for M_EACH (item, list, list_string_t) {
printf ("Sort Item = %s\n", string_get_cstr(*item) );
}
// Split a string into a list.
string_set_str(tmpstr, "HELLO;JOHN;HOW;ARE;YOU");
astring_split(grow, tmpstr, ';');
for M_EACH (item, grow, list_string_t) {
list_string_split(list, tmpstr, ';');
// Iterate over the splitted list
for M_EACH (item, list, list_string_t) {
printf ("Split Item = %s\n", string_get_cstr(*item) );
}
} // 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;
}
+16 -7
View File
@@ -24,22 +24,25 @@
/* Define the needed data structure : */
// Define a dictionnary of constant string --> integer
DICT_DEF2(dict_mph, const char *, M_CSTR_OPLIST, uint32_t, M_DEFAULT_OPLIST)
#define M_OPL_dict_mph_t() DICT_OPLIST(dict_mph, M_CSTR_OPLIST, M_DEFAULT_OPLIST)
// Define a dictionnary of constant string --> integer and register it.
DICT_DEF2(dict_mph, const char *, M_CSTR_OPLIST, uint32_t, M_BASIC_OPLIST)
#define M_OPL_dict_mph_t() DICT_OPLIST(dict_mph, M_CSTR_OPLIST, M_BASIC_OPLIST)
// Defin an array of integer
// Define an array of integer to store the value and register it.
ARRAY_DEF(array_value, uint32_t) // Start from 1. 0 is 'None'
#define M_OPL_array_value_t() ARRAY_OPLIST(array_value)
// Defin an array of integer
// Define an array of integer to store the seed and register it.
ARRAY_DEF(array_seed, int32_t)
#define M_OPL_array_seed_t() ARRAY_OPLIST(array_seed)
// Define algorithms on array_seed
ALGO_DEF(array_seed, array_seed_t)
// Define an array of constant string that are ordered by their size.
ARRAY_DEF(array_cstr, const char *, M_CSTR_OPLIST)
// Register it globally but with a custom CMP operator
static inline int array_cstr_cmp(const array_cstr_t a, const array_cstr_t b) {
// We compare only the size
size_t sa = array_cstr_size(a);
size_t sb = array_cstr_size(b);
return (sa > sb) ? -1 : (sa < sb);
@@ -121,7 +124,7 @@ CreateMinimalPerfectHash2(array_seed_t seed, array_value_t value,
enought. */
for(bool cont = true; cont ; ) {
cont = false;
array_seed_clean(slots);
array_seed_reset(slots);
for M_EACH(it, *b, array_cstr_t) {
size_t s = hash(d, *it) % size;
if (*array_value_get(value, s) != 0 || array_seed_contain_p(slots, s)){
@@ -191,7 +194,11 @@ static void
dict_read_from_file(dict_mph_t dict, array_string_t arr, const char filename[])
{
FILE *f = fopen(filename, "rt");
if (!f) abort();
if (!f) {
fprintf(stderr, "ERROR: Cannot open %s\n", filename);
exit(2);
}
uint32_t line = 1;
M_LET(str, string_t) {
while (!feof(f) && !ferror(f)) {
@@ -234,7 +241,9 @@ test(array_seed_t seed, array_value_t value, dict_mph_t dict)
int main(int argc, const char *argv[])
{
// Create arr as array_string_t, dict as dist_mph_t and seed as array_seed_t
M_LET(arr, array_string_t) M_LET(dict, dict_mph_t) M_LET(seed, array_seed_t)
// and value as array_value_t
M_LET(value, array_value_t) {
const char *filename = (argc > 1) ? argv[1] :"/usr/share/dict/words";
dict_read_from_file(dict, arr, filename);
+9 -4
View File
@@ -4,6 +4,7 @@
#include "m-array.h"
#include "m-string.h"
// Define an array of integer
ARRAY_DEF(array_int, int)
typedef struct {
@@ -25,7 +26,7 @@ static void tape_devance(tape_t tape) { if (tape->pos > 0) tape->pos--; }
typedef struct {
string_t code;
array_int_t bracket_map; // Should use map when possible.
array_int_t bracket_map;
} program_t[1];
static void program_init(program_t p, string_t text) {
@@ -47,8 +48,8 @@ static void program_init(program_t p, string_t text) {
int left;
array_int_pop_back(&left, leftstack);
int right = pc;
*array_int_get_at (p->bracket_map, left) = right;
*array_int_get_at (p->bracket_map, right) = left;
*array_int_safe_get (p->bracket_map, left) = right;
*array_int_safe_get (p->bracket_map, right) = left;
}
pc++;
@@ -98,7 +99,11 @@ static void program_run(program_t p){
static void read_file(string_t str, const string_t filename) {
FILE *f = fopen(string_get_cstr(filename), "rt");
if (!f) abort();
if (!f) {
fprintf(stderr, "ERROR: Cannot open %s\n", string_get_cstr(filename));
exit(2);
}
// Read the full FILE in the string
string_fgets (str, f, STRING_READ_FILE);
fclose(f);
}
-63
View File
@@ -1,63 +0,0 @@
#include <stdio.h>
#include <gmp.h>
#include "m-variant.h"
#include "m-string.h"
#include "m-dict.h"
#include "m-array.h"
/* Define a variant over two integers named integer_t
Notice than mpz_t has special init & clear functions
mpz_init & mpz_clear.
This is handle by the library.
*/
VARIANT_DEF2(my_integer,
(n, long long, M_DEFAULT_OPLIST),
(z, mpz_t, M_CLASSIC_OPLIST(mpz)))
/* Define the oplist associated to this variant */
#define MY_INTEGER_OPLIST VARIANT_OPLIST(my_integer, M_DEFAULT_OPLIST, M_CLASSIC_OPLIST(mpz))
/* Define a dictionary of string --> integer named dict_my_t */
DICT_DEF2(my_dict,
string_t, STRING_OPLIST,
my_integer_t, MY_INTEGER_OPLIST)
/* Define the oplist associated to this dictionary */
#define MY_DICT_OPLIST DICT_OPLIST(my_dict, STRING_OPLIST, MY_INTEGER_OPLIST)
/* Define an array of such dictionary named array_my_t */
ARRAY_DEF(my_array, my_dict_t, MY_DICT_OPLIST)
/* Define the oplist associated to this array of dictionary of variant */
#define MY_ARRAY_OPLIST ARRAY_OPLIST(my_array, MY_DICT_OPLIST)
int main(void)
{
M_LET(z, MY_INTEGER_OPLIST) /* Define & init & clear an instance of a variant of integer */
M_LET(dict, MY_DICT_OPLIST) /* Define & init & clear an instance of a dictionary of variant */
M_LET(array, MY_ARRAY_OPLIST) /* Define & init & clear an intance of an array of dictionary of variant */
M_LET(gmp, M_CLASSIC_OPLIST(mpz)) /* M_LET allows even with non container type */
{
my_integer_set_n (z, 17LL); // Set z as the long long 17
my_dict_set_at(dict, STRING_CTE("n1"), z); // Push it in the dictionary
mpz_set_str(gmp, "25446846874687468746874687468746874686874", 10); // Set gmp to a very long integer.
my_integer_set_z (z, gmp); // Set z as the mpz_t variable
my_dict_set_at(dict, STRING_CTE("n2"), z); // Push it in the dictionary
my_array_push_back (array, dict); // Push the dictionary in the array
// Iterate over the array container
for M_EACH(item, array, MY_ARRAY_OPLIST) {
// Iterate over the dictionary container
for M_EACH(p, *item, MY_DICT_OPLIST) {
// Dictionary iterator are pair (key,value)
if (my_integer_n_p(p->value)) {
printf ("It is a long long, value = %lld\n",
*my_integer_get_n(p->value));
}
if (my_integer_z_p(p->value)) {
printf ("It is a mpz_t, value =");
mpz_out_str(stdout, 10, *my_integer_get_z(p->value));
printf("\n");
}
}
}
} /* All variables are automatically cleared beyond this point */
}
+3 -3
View File
@@ -4,7 +4,7 @@
/* Register a dynamic seed to M*LIB hash function.
This shall be done before any M*LIB header inclusion. */
unsigned long long rand_seed;
#define M_HASH_SEED rand_seed
#define M_USE_HASH_SEED rand_seed
#include "m-array.h"
#include "m-dict.h"
@@ -84,8 +84,8 @@ DICT_DEF2(dict_json, string_t, STRING_OPLIST, json_t, JSON_OPLIST)
ARRAY_DEF(array_json, json_t, JSON_OPLIST)
VARIANT_DEF2(variant_json,
(boolean, bool, M_OPEXTEND(M_DEFAULT_OPLIST, OUT_STR(boolean_out_str), IN_STR(boolean_in_str M_IPTR)) ),
(real, float, M_OPEXTEND (M_DEFAULT_OPLIST, OUT_STR(real_out_str), IN_STR(real_in_str M_IPTR))),
(boolean, bool, M_OPEXTEND(M_BASIC_OPLIST, OUT_STR(boolean_out_str), IN_STR(boolean_in_str M_IPTR)) ),
(real, float, M_OPEXTEND (M_BASIC_OPLIST, OUT_STR(real_out_str), IN_STR(real_in_str M_IPTR))),
(array, array_json_t, ARRAY_OPLIST(array_json, JSON_OPLIST)),
(dict, dict_json_t, DICT_OPLIST(dict_json, STRING_OPLIST, JSON_OPLIST)))
+9 -5
View File
@@ -10,7 +10,7 @@
order to show/test the good chaining of the structures */
TUPLE_DEF2(symbol, (type, int), (name, string_t))
#define M_OPL_symbol_t() TUPLE_OPLIST(symbol, M_DEFAULT_OPLIST, STRING_OPLIST)
#define M_OPL_symbol_t() TUPLE_OPLIST(symbol, M_BASIC_OPLIST, STRING_OPLIST)
ARRAY_DEF(symbol_list, symbol_t)
#define M_OPL_symbol_list_t() ARRAY_OPLIST(symbol_list, M_OPL_symbol_t())
@@ -19,13 +19,13 @@ TUPLE_DEF2(record, (fields, symbol_list_t))
#define M_OPL_record_t() TUPLE_OPLIST(record, M_OPL_symbol_list_t())
TUPLE_DEF2(my_tuple, (name, string_t), (value, int))
#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple)
#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple, STRING_OPLIST, M_BASIC_OPLIST)
ARRAY_DEF(my_list_of_tuple, my_tuple_t)
#define M_OPL_my_list_of_tuple_t() ARRAY_OPLIST(my_list_of_tuple)
TUPLE_DEF2(my_tuple_of_tuple, (name, string_t), (inner_tuple, my_tuple_t))
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple)
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple, STRING_OPLIST, M_OPL_my_tuple_t() )
LIST_DEF(list_of_tuple_of_tuple, my_tuple_of_tuple_t)
#define M_OPL_list_of_tuple_of_tuple_t() LIST_OPLIST(list_of_tuple_of_tuple, M_OPL_my_tuple_of_tuple_t() )
@@ -37,11 +37,11 @@ BUFFER_DEF(trbuff, my_triple_tuple_t, 100, BUFFER_QUEUE)
#define M_OPL_trbuff_t() BUFFER_OPLIST(trbuff, M_OPL_my_triple_tuple_t())
TUPLE_DEF2(my_junction, (active, bool), (buffer, trbuff_t))
#define M_OPL_my_junction_t() TUPLE_OPLIST(my_junction, M_DEFAULT_OPLIST, M_OPL_trbuff_t())
#define M_OPL_my_junction_t() TUPLE_OPLIST(my_junction, M_BASIC_OPLIST, M_OPL_trbuff_t())
TUPLE_DEF2(mlib_point, (x, int), (y, int))
#define M_OPL_mlib_point_t() \
TUPLE_OPLIST(mlib_point, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST)
TUPLE_OPLIST(mlib_point, M_BASIC_OPLIST, M_BASIC_OPLIST)
TUPLE_DEF2(mlib_points, (first_ref, mlib_point_ptr, M_PTR_OPLIST),
(second_ref, mlib_point_ptr, M_PTR_OPLIST),
@@ -51,6 +51,9 @@ TUPLE_DEF2(mlib_points, (first_ref, mlib_point_ptr, M_PTR_OPLIST),
static void let2(void)
{
// Initialize p1 as mlib_point_t with (4,4)
// and p2 as mlib_point_t with (5,5)
// and pair as mlib_point_t with default value
M_LET((p1, 4, 4), (p2, 5, 5), mlib_point_t) {
M_LET(pair, mlib_points_t) {
pair->first_ref = p1;
@@ -68,6 +71,7 @@ static void let2(void)
static void let(void)
{
// Let's initialize all the declared types
M_LET(s, symbol_t)
M_LET(l, symbol_list_t)
M_LET(r,record_t)
+38
View File
@@ -0,0 +1,38 @@
#include <stdio.h>
#include "m-array.h"
#include "m-string.h"
/* This example show ARRAY_DEF usage with string,
M_LET macro usage with complex initialization condition:
how to initialize a dynamic array and initialize it with the given arguments.
It show also the M_EACH keywork
*/
// Let's create a dynamic array of string_t and register it globaly
// a so called std::vector<std::string> in C++
ARRAY_DEF(vector_string, string_t)
#define M_OPL_vector_string_t() ARRAY_OPLIST(vector_string, STRING_OPLIST)
int main(void)
{
// Let's define a new string named str
M_LET(str, string_t)
// Let's define msg as a vector_array_t
M_LET( (msg, STRING_CTE("Hello"), STRING_CTE("C"), STRING_CTE("World!"), STRING_CTE("Let's"), STRING_CTE("discover"), STRING_CTE("M*LIB!")), vector_string_t) {
// Iterate over all words of the array msg
for M_EACH(word, msg, vector_string_t) {
// Cat the current word into the target string
string_cat(str, *word);
// Also add a space character
string_push_back(str, ' ');
}
// Let's define another string and set it to a formatted value.
M_LET( (count, "\nTo display this it uses \"vector\" of %zu strings!", vector_string_size(msg)), string_t) {
string_cat(str, count);
}
// Print the result
printf("%s\n", string_get_cstr(str) );
}
return 0;
}
+16
View File
@@ -0,0 +1,16 @@
/*
* Micro example to test if M*LIB supports not using stdio.h
*/
#define M_USE_STDIO 0
#define M_RAISE_FATAL(...) abort()
#include "m-array.h"
ARRAY_DEF(arr, int)
int main(void) {
arr_t a;
arr_init(a);
arr_push_back(a, 4);
arr_clear(a);
return 0;
}
+9 -8
View File
@@ -4,6 +4,14 @@
#include "m-rbtree.h"
// Let's define one utility function.
static void *xmalloc(size_t n)
{
void *p = malloc (n);
if (!p) abort();
return p;
}
// Let's define a new type.
typedef struct {
int key;
@@ -12,7 +20,7 @@ typedef struct {
#define SIZE 256
void *xmalloc(size_t n);
// Let's define the prototypes of the methods of this new type.
void my_type_init(my_type_t x);
void my_type_clear(my_type_t x);
void my_type_init_set(my_type_t x, const my_type_t y);
@@ -24,13 +32,6 @@ void my_type_out_str(FILE *f, const my_type_t x);
bool my_type_in_str(my_type_t x, FILE *f);
void my_type_rand(my_type_t x);
void *xmalloc(size_t n)
{
void *p = malloc (n);
if (!p) abort();
return p;
}
// Let's define its constructor
void my_type_init(my_type_t x)
{
+53
View File
@@ -0,0 +1,53 @@
#include <stdio.h>
#include <string.h>
#include "m-string.h"
#define MAX_COLUMN 80
static void format(FILE *f)
{
string_t s;
string_init(s);
while (string_fgets(s, f, STRING_READ_PURE_LINE) == true)
{
size_t n = string_size(s);
if (n > 0 && string_get_char(s, n-1) == '\\' && n < MAX_COLUMN) {
string_left(s, n-1);
while (n < MAX_COLUMN-1) {
string_push_back(s, ' ');
n++;
}
string_push_back(s, '\\');
}
if (n >= MAX_COLUMN && string_get_char(s, n-1) == '\\') {
n--;
string_left(s, n);
while (n >= MAX_COLUMN-2 && string_get_char(s, n-1) == ' ') {
n--;
string_left(s, n);
}
string_push_back(s, ' ');
string_push_back(s, '\\');
}
printf("%s\n", string_get_cstr(s));
}
string_clear(s);
}
int main(int argc, const char *argv[])
{
if (argc < 2)
{
fprintf(stderr, "ERROR: Missing argument filename.\nUSAGE: %s filename.h\n", argv[0]);
exit(1);
}
FILE *f = fopen(argv[1], "rt");
if (!f) {
fprintf(stderr, "ERROR: Cannot open filename '%s' .h\n", argv[1]);
exit(2);
}
format(f);
fclose(f);
exit(0);
}
+97
View File
@@ -0,0 +1,97 @@
#include "m-array.h"
#include "m-string.h"
// Define an array of string_t. Since the oplist of string_t is registered globaly
// there is no need to give it to this definition.
ARRAY_DEF(str_array, string_t)
// First the verbose way and (nearly) macro free:
static void main_macrofree(void)
{
str_array_t tab_name;
str_array_init(tab_name);
// Push some elements in the array (long way)
str_array_push_back(tab_name, STRING_CTE("My"));
str_array_push_back(tab_name, STRING_CTE("CD"));
str_array_push_back(tab_name, STRING_CTE("IS"));
str_array_push_back(tab_name, STRING_CTE("OUT"));
// Overwrite element 1 of the array.
str_array_set_at(tab_name, 1, STRING_CTE("DVD"));
// Finaly rewrite 1 element of the array
string_set_str(*str_array_get(tab_name, 1), "BLU-RAY");
// Format some strings and push them back in the array
string_t format;
string_init_printf(format, "There are %d elements", str_array_size(tab_name));
str_array_push_back(tab_name, format);
string_printf(format, "There is a capacty of %d", str_array_capacity(tab_name));
string_replace_all_str(format, "capacty", "capacity");
str_array_push_back(tab_name, format);
string_printf(format, "The third element is '%s'", string_get_cstr(*str_array_get(tab_name, 2)));
str_array_push_back(tab_name, format);
string_clear(format);
// Display the content of the array.
str_array_it_t it;
int i = 0;
for (str_array_it(it, tab_name) ; !str_array_end_p(it); str_array_next(it)) {
printf("item[%d] = '%s'\n", i, string_get_cstr(*str_array_cref(it)) );
i++;
}
// Clear the array
str_array_clear(tab_name);
}
// Then the short version with macros.
// For this we need to register the oplist of the array of string globally.
#define M_OPL_str_array_t() ARRAY_OPLIST(str_array, STRING_OPLIST)
static void main_macro(void)
{
// Define and fill an array of string with some elements in it:
M_LET( (tab_name, STRING_CTE("My"), STRING_CTE("CD"), STRING_CTE("IS"), STRING_CTE("OUT")), str_array_t) {
// Overwrite element 1 of the array.
str_array_set_at(tab_name, 1, STRING_CTE("DVD"));
// Finaly rewrite 1 element of the array
string_set_str(*str_array_get(tab_name, 1), "BLU-RAY");
// Format some strings and push them back in the array
M_LET(format, string_t) {
string_printf(format, "There are %d elements", str_array_size(tab_name));
str_array_push_back(tab_name, format);
string_printf(format, "There is a capacty of %d", str_array_capacity(tab_name));
string_replace_all_str(format, "capacty", "capacity");
str_array_push_back(tab_name, format);
string_printf(format, "The third element is '%s'", string_get_cstr(*str_array_get(tab_name, 2)));
str_array_push_back(tab_name, format);
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
// Set format to a formated string
// In C11, we can mix string_t and char *.
// We can also use M_CSTR to create a printf formated string.
string_sets(format, "FILE=", getenv("PWD"), "/", *str_array_get(tab_name, 2), M_CSTR("-%zu.txt", str_array_size(tab_name) ));
str_array_push_back(tab_name, format);
#endif
} // beyond this point format is cleared
// Display the content of the array.
int i = 0;
for M_EACH(item, tab_name, str_array_t) {
printf("item[%d] = '%s'\n", i, string_get_cstr(*item) );
i++;
}
} // beyond this point tab_name is cleared
}
int main(void)
{
printf("Version macrofree:\n");
main_macrofree();
printf("Version macro:\n");
main_macro();
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
#include <stdio.h>
#include "m-string.h"
#include "m-dict.h"
#include "m-array.h"
/* Definition of an associative map string_t --> size_t */
DICT_DEF2(dict_str, string_t, size_t)
#define M_OPL_dict_str_t() DICT_OPLIST(dict_str, STRING_OPLIST, M_BASIC_OPLIST)
/* Definition of an array of string_t */
ARRAY_DEF(vector_str, string_t)
#define M_OPL_vector_str_t() ARRAY_OPLIST(vector_str, STRING_OPLIST)
int main(void)
{
// Construct an array of string, performing a convertion of the C const char *
// into a proper string_t at real time and push then into a dynamic array
// that is declared, initialized and cleared.
M_LET( (words, ("This"), ("is"), ("a"), ("useless"), ("sentence"), ("."),
("It"), ("is"), ("used"), ("a"), ("bit"), ("to"), ("count"), ("words"), (".") ),
vector_str_t) {
// Print the arrays.
printf("The words are: ");
vector_str_out_str(stdout, words);
printf("\n");
// Count the words.
M_LET(map, dict_str_t) {
// Count the words into the dictionnary 'map'
for M_EACH(w, words, vector_str_t) {
(*dict_str_safe_get(map, *w)) ++;
}
// Print the count:
for M_EACH(p, map, dict_str_t) {
// In C11 version we can use the M_PRINT macro that simplifies formatting.
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
M_PRINT(p->value, " occurences of ", p->key, "\n");
#else
printf ("%zu occurences of %s\n", p->value, string_get_cstr(p->key));
#endif
}
}
}
}
+37
View File
@@ -0,0 +1,37 @@
/* Based on https://en.cppreference.com/w/cpp/algorithm/for_each
Need to be built in C11 mode */
#include <stdio.h>
#include "m-array.h"
#include "m-algo.h"
/* Define a dynamic array of int */
ARRAY_DEF(vector_int, int)
#define M_OPL_vector_int_t() ARRAY_OPLIST(vector_int)
/* Define operator increment on int */
#define INC(n) (n)++
int main(void)
{
M_LET( (nums, 3, 4, 2, 8, 15, 267), vector_int_t) {
// Print the array before
printf ("before:");
ALGO_FOR_EACH(nums, vector_int_t, M_PRINT, " ");
printf ("\n");
// Increment each element of the array
ALGO_FOR_EACH(nums, vector_int_t, INC);
// Print the array after
printf ("after: ");
ALGO_FOR_EACH(nums, vector_int_t, M_PRINT, " ");
printf ("\n");
// Sum the elements of the array
int sum = 0;
ALGO_REDUCE(sum, nums, vector_int_t, add);
M_PRINT("sum = ", sum, "\n");
}
return 0;
}
+89
View File
@@ -0,0 +1,89 @@
#include "m-tuple.h"
#include "m-array.h"
#include "m-algo.h"
#include "m-funcobj.h"
#include "m-serial-json.h"
#include "m-string.h"
/* Define the employee class */
TUPLE_DEF2(employee,
(name, string_t),
(age, int),
(idnum, int))
/* Register globaly the employee_t oplist */
#define M_OPL_employee_t() TUPLE_OPLIST(employee, STRING_OPLIST, M_BASIC_OPLIST, M_BASIC_OPLIST)
/* Define an array of employee, register the oplist and define further algorithms on it */
ARRAY_DEF(vector_employee, employee_t)
#define M_OPL_vector_employee_t() ARRAY_OPLIST(vector_employee, M_OPL_employee_t())
ALGO_DEF(vector_employee, vector_employee_t)
/* Define the function object to select the sort order.
* It is named 'compare_by' and is an instance of the interface
* 'vector_employee_cmp_obj' created by ALGO_DEF.
*/
FUNC_OBJ_INS_DEF(compare_by /* name of the instance */,
vector_employee_cmp_obj /* name of the interface */,
(a, b) /* name of the input parameters of the function like object. The type are inherited from the interface. */, {
/* code of the function object */
if (string_equal_str_p(self->sort_field, "name"))
return string_cmp(a->name, b->name);
else if (string_equal_str_p(self->sort_field, "age"))
return a->age < b->age ? -1 : a->age > b->age;
else
return a->idnum < b->idnum ? -1 : a->idnum > b->idnum;
},
/* Additional fields stored in the function object */
(sort_field, string_t) )
#define M_OPL_compare_by_t() FUNC_OBJ_INS_OPLIST(compare_by, STRING_OPLIST)
// Let's read an array of person from the given JSON file
static void read(vector_employee_t base, const char filename[])
{
m_serial_return_code_t ret;
// Open the file
FILE *f = fopen(filename, "rt");
if (!f) {
// Handle errors
fprintf(stderr, "ERROR: Cannot open file '%s'.\n", filename);
exit(2);
}
// Initialize the JSON serializer with this file
M_LET( (in,f), m_serial_json_read_t)
// Read the JSON file and fill in 'base' with it.
ret = vector_employee_in_serial(base, in);
// Let's handle serialization error
if (ret != M_SERIAL_OK_DONE) {
fprintf(stderr, "ERROR: Cannot read JSON data from file '%s'.\nParsing stops at:\n", filename);
while (!feof(f)) { fputc(fgetc(f), stdout); }
fclose(f);
exit(2);
}
// Close the FILE
fclose(f);
}
int main(void)
{
M_LET(emps, vector_employee_t) {
/* Code to populate database from JSON */
read(emps, "ex11-algo02.json");
// Sort the database by employee ID number
M_LET( (cmp, STRING_CTE("idnum")), compare_by_t )
vector_employee_sort_fo(emps, compare_by_as_interface(cmp));
M_PRINT("Employees sorted by idnum are: ", (emps, vector_employee_t), "\n" );
// Sort the database by employee name
M_LET( (cmp, STRING_CTE("name")), compare_by_t )
vector_employee_sort_fo(emps, compare_by_as_interface(cmp));
M_PRINT("Employees sorted by name are: ", (emps, vector_employee_t), "\n" );
// End
}
return 0;
}
+9
View File
@@ -0,0 +1,9 @@
[
{ "name": "John Doe", "age": 32, "idnum": 14528},
{ "name": "Clint Smith", "age": 31, "idnum": 14529},
{ "name": "Linda Cameron", "age": 20, "idnum": 14527},
{ "name": "Cameron Carrey", "age": 25, "idnum": 14526},
{ "name": "Marty Brown", "age": 26, "idnum": 14525},
{ "name": "Donald Cow", "age": 45, "idnum": 14520}
]
+232
View File
@@ -0,0 +1,232 @@
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "m-tuple.h"
#include "m-tree.h"
#include "m-worker.h"
#include "m-string.h"
#include "m-atomic.h"
/* Define the comparison function for atomic_uint type
to sort the atomic unsigned int with the biggest value first. */
static inline int atomic_uint_cmp(const atomic_uint *a, const atomic_uint *b)
{
unsigned ai = atomic_load(a), bi = atomic_load(b);
return ai > bi ? -1 : ai < bi;
}
/* Define the oplist for atomic_uint and register it globally.
This oplist extends the basic oplist by:
* disabling HASH for atomic as the default hash method won't work.
* providing the methods for CMP, INIT_SET and SET operators (with their API adaptator) */
#define M_OPL_atomic_uint() M_OPEXTEND(M_BASIC_OPLIST, HASH(0), CMP(API_6(atomic_uint_cmp)), INIT_SET(API_2(atomic_store)), SET(API_2(atomic_store)))
/* Define a directory as a tree where each node contains:
* the number of lines of the files in this directory,
* and the name of the directory/
Since we want to sort with the number of lines only, we extend the oplist of a string by disabling the compare method.
So first, let's define the node as a tuple of such elements:
*/
M_TUPLE_DEF2( dir, (nlines, atomic_uint), (name, m_string_t, M_OPEXTEND(M_STRING_OPLIST, CMP(0))))
/* Register globally the oplist of this tuple */
#define M_OPL_dir_t() M_TUPLE_OPLIST(dir, M_OPL_atomic_uint(), M_STRING_OPLIST)
/* Define a hierarchical tree of directory.
Note that it will use the globally registered oplist associated to dir_t to use it */
M_TREE_DEF(tree, dir_t)
/* Maximum number of characters read by file */
#define MAX_READ_BUFFER 8192
/* Maximum number of directory to scan */
#define MAX_DIRECTORY 100000
/* Define the pool of worker threads */
m_worker_t workers;
/* Global synchronous block for all threads */
m_worker_sync_t workers_block;
/* Add a specialization of the spawn function for the scan_file function.
This functions takes as input an iterator of a tree (treated as a POD data),
and a file name */
M_WORKER_SPAWN_DEF2(scan_file, (parent, tree_it_t, M_POD_OPLIST), (filename, m_string_t) )
/* Add either the root node or a child to parent in function of the existence of parent */
static tree_it_t
add_directory(tree_it_t parent, const m_string_t dirname)
{
if (tree_end_p(parent)) {
return tree_emplace_root( tree_tree(parent), 0, dirname);
} else {
return tree_emplace_child(parent, 0, dirname);
}
}
/* count the number of end of line character in the buffer */
static unsigned
count_eol(size_t num, const char buffer[num])
{
unsigned count = 0;
for(size_t i = 0; i < num; i++) {
count += buffer[i] == '\n';
}
return count;
}
/* Test if a filename suffix ends with a C++ or C suffix */
static bool
is_a_c_file(const m_string_t filename)
{
return (m_string_end_with_str_p(filename, ".c")
|| m_string_end_with_str_p(filename, ".h")
|| m_string_end_with_str_p(filename, ".cpp")
|| m_string_end_with_str_p(filename, ".hpp"));
}
/* Scan the file and count its number of lines */
static void
scan_file(tree_it_t parent, m_string_t filename)
{
FILE *f = fopen(m_string_get_cstr(filename), "rt");
if (f == NULL) {
fprintf(stderr, "ERROR: Cannot open %s as a text file.\n", m_string_get_cstr(filename) );
exit(1);
}
/* Read the FILE per bulk of MAX_READ_BUFFER */
char buffer[MAX_READ_BUFFER];
unsigned count = 0;
size_t num;
do {
num = fread (buffer, 1, MAX_READ_BUFFER, f);
count += count_eol(num, buffer);
} while (num == MAX_READ_BUFFER);
fclose(f);
/* Adding the number of lines to the parent directory */
dir_t *d = tree_ref(parent);
/* atomic add because the scan of files is done in parallel */
atomic_fetch_add( &(*d)->nlines, count );
}
/* Scan the directories recursively for all files */
static void
scan_directories(tree_it_t parent, const m_string_t dirname)
{
tree_it_t it = add_directory(parent, dirname);
m_string_t filename;
m_string_init(filename);
DIR *dir = opendir(m_string_get_cstr(dirname));
if (dir == NULL) {
fprintf(stderr, "ERROR: Cannot open %s as a directory.\n", m_string_get_cstr(dirname) );
exit(1);
}
// Scan all entries in the directory
struct dirent *entry = readdir(dir);
while (entry) {
// Ignore hidden entries (including '.' and '..')
if (entry->d_name[0] != '.') {
// Construct the path to the filename by concatenating dirname, "/" and d_name
m_string_sets(filename, dirname, "/", entry->d_name);
// Get the property of this filename
struct stat buf;
int err = stat(m_string_get_cstr(filename), &buf);
if (err != 0) {
fprintf(stderr, "ERROR: Cannot stat %s\n", m_string_get_cstr(filename));
exit(2);
}
// Further scanning in function of the kind of entry
if (S_ISDIR(buf.st_mode)) {
scan_directories(it, filename);
} else if (is_a_c_file(filename)) {
// Spawn a scan of file to available workers or run it ourselves
m_worker_spawn_scan_file(workers_block, scan_file, it, filename);
}
}
// Next entry in the directory
entry = readdir(dir);
}
closedir(dir);
m_string_clear(filename);
}
/* Consolidate all lines number to the parent directory */
static void
consolidate_directories(tree_t directories)
{
// Scan all entries, first the children, then the parent
for(tree_it_t it = tree_it_post(directories) ; !tree_end_p(it) ; tree_next_post(&it) ) {
dir_t *parent = tree_up_ref(it);
dir_t *myself = tree_ref(it);
if (parent != NULL) {
// Add the child number of lines to the parent
atomic_fetch_add_explicit(&(*parent)->nlines, (*myself)->nlines, memory_order_relaxed);
}
// Sort the data of the children by the number of lines
tree_sort_child(it);
}
}
/* Print the consolidated results on stdout */
static void
print_result(tree_t directories)
{
// Scan all entries, first the parent, then the children
for(tree_it_t it = tree_it(directories) ; !tree_end_p(it) ; tree_next(&it) ) {
int i, depth = tree_depth(it);
for(i = 0; i < depth; i++) printf("+");
for( ; i < 8; i++) printf(" ");
const dir_t *d = tree_cref(it);
printf("%6u %s\n", (unsigned) (*d)->nlines, m_string_get_cstr( (*d)->name ) );
}
}
int main(int argc, const char *argv[])
{
tree_t directories;
m_string_t str;
printf("Count the number of C/C++ lines of code\n");
if (argc < 2) {
fprintf(stderr, "ERROR. Usage is '%s <directory>'.\n", argv[0]);
exit(1);
}
/* Initialize the worker threads */
m_worker_init(workers);
/* Init the tree, reserve for at least the number of max directory
and prevent any further increase of allocation:
this is to ensure that other threads can deref a dir safely */
tree_init(directories);
tree_reserve(directories, MAX_DIRECTORY);
tree_lock(directories, true);
m_string_init_set_cstr(str, argv[1]);
tree_it_t it = tree_it_end(directories);
/* Main processing */
m_worker_start(workers_block, workers);
scan_directories(it, str);
worker_sync(workers_block);
consolidate_directories(directories);
print_result(directories);
/* Clear everything & quit */
m_string_clear(str);
tree_clear(directories);
m_worker_clear(workers);
exit(0);
}
+82
View File
@@ -0,0 +1,82 @@
// Based on https://github.com/nanopb/nanopb/blob/master/examples/simple/simple.c
#include <stdio.h>
#include "m-serial-json.h"
#include "m-tuple.h"
#include "m-string.h"
// Define a structure with one field
TUPLE_DEF2(SimpleMessage,
(lucky_number, int))
int main(void)
{
string_t buffer;
m_serial_return_code_t status;
/* Let's define a string 'buffer' that will receive the JSON representation of our message*/
string_init(buffer);
/* Encode our message */
{
SimpleMessage_t message;
SimpleMessage_init(message);
/* Create a stream that will write to our string buffer. */
m_serial_str_json_write_t stream;
m_serial_str_json_write_init(stream, buffer);
/* Fill in the lucky number */
message->lucky_number = 13;
/* Now we are ready to encode the message! */
status = SimpleMessage_out_serial(stream, message);
/* Then just check for any errors.. */
if (status != M_SERIAL_OK_DONE)
{
printf("Encoding failed: %d\n", status);
return 1;
}
/* Clear the objets */
m_serial_str_json_write_clear(stream);
SimpleMessage_clear(message);
}
/* Now we could transmit the message over network, store it in a file
* It is represented in a string 'buffer'
* but we are doing it right now.
*/
{
/* Allocate another space for the decoded message. */
SimpleMessage_t message;
SimpleMessage_init(message);
/* Create a stream that reads from the buffer. */
m_serial_str_json_read_t stream;
m_serial_str_json_read_init(stream, string_get_cstr(buffer));
/* Now we are ready to decode the message. */
status = SimpleMessage_in_serial(message, stream);
/* Check for errors... */
if (status != M_SERIAL_OK_DONE)
{
printf("Decoding failed: %d\n", status);
return 1;
}
/* Print the data contained in the message. */
printf("Your lucky number was %d!\n", message->lucky_number);
/* Clear the objets */
m_serial_str_json_read_clear(stream);
SimpleMessage_clear(message);
}
string_clear(buffer);
return 0;
}
+63
View File
@@ -0,0 +1,63 @@
#include "m-serial-json.h"
#include "m-tuple.h"
#include "m-array.h"
/* Basic example to show JSON serialization */
// Let's define a 'person' composed of several fields.
TUPLE_DEF2(person,
(surname, string_t),
(age, int),
(present, bool)
)
// Register the oplist of this tuple globaly
#define M_OPL_person_t() TUPLE_OPLIST(person, STRING_OPLIST, M_BASIC_OPLIST, M_BOOL_OPLIST )
// Let's define an array of person
ARRAY_DEF(base, person_t)
// Register the oplist of this array globaly
#define M_OPL_base_t() ARRAY_OPLIST(base, M_OPL_person_t())
// Let's read an array of person from the given JSON file
static void read(base_t base, const char filename[])
{
m_serial_read_t in;
m_serial_return_code_t ret;
// Open the file
FILE *f = fopen(filename, "rt");
if (!f) {
fprintf(stderr, "ERROR: Cannot open file '%s'.\n", filename);
exit(2);
}
// Initialize the serializer with the file
m_serial_json_read_init(in, f);
// Read the array
ret = base_in_serial(base, in);
if (ret != M_SERIAL_OK_DONE) {
fprintf(stderr, "ERROR: Cannot read JSON data from file '%s'.\n", filename);
exit(2);
}
// Let's close & clear all
m_serial_json_read_clear(in);
fclose(f);
}
int main(void)
{
// Let's have base as a base_t
M_LET(base, base_t) {
// Read the JSON file and fill-in base
read(base, "ex11-json01.json");
base_emplace_back(base, STRING_CTE("John"), 40, false);
// Print the contents of base:
printf ("List of presents:\n");
for M_EACH(el, base, base_t) {
if ((*el)->present) {
printf("%s\n", string_get_cstr((*el)->surname));
}
}
}
exit(0);
}
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more