* math: fix adjoint of Matrix2
Fix the adjoint of the Matrix2x2 implementation in the math module. This
also fixes the calculation of the inverse which depends on the adjoint.
* update release notes
Add gcd and lcm functions to calculate the greatest common divisor (gcd)
and the least common multiple (lcm) to the math module. This will also
work for BigInts that implements its own gcd/lcm.
Add inverse, conjugate, and equals functions to the Complex numbers. Add
an IMAGINARY constant to represent the imaginary unit. Also, add unit
tests for different types.
* sort: add is_sorted
Add is_sorted function to check whether a list is sorted or not. Sort
order (ascending or descending) will be detected by looking at the data.
Add tests.
* update the release notes
* refactor: use lambda
* sort: extract partition from quicksort
Extract the partition logic from quicksort into a macro. This allows to
reuse the partition logic for, e.g., the quickselect algorithm.
* sort: implement quickselect
implement Hoare's selection algorithm (quickselect) on the basis of the
already implemented quicksort. Quickselect allows to find the kth
smallest element in a unordered list with an average time complexity of
O(N) (worst case: O(N^2)).
* add quicksort benchmark
Create a top-level benchmarks folder. Add the benchmark implementation
for the quicksort algorithm.
Benchmarks can then be run in the same way as unit tests from the
root folder with:
c3c compile-benchmarks benchmarks/stdlib/sort
Ensure that the URL alphabet for base64 is used with the urlencode
functions (urlencode, urlencode_buffer, urlencode_temp and
urlencode_new) are used. Add a new test.
Fix the base64 decoding. If there's an 'A' character in the encoded
text, the base64 decode function returns an INVALID_PADDING error. The
reason lies in the way Base64Decoder.init tries to find a suitable
invalid character. Fix this by defining the invalid character as 0xff
(which is already the case for a decoding without padding).
This error has not been caught by the test harness, because no test
contains an 'A' character in the the encoded text yet. Add a new test.
* io: implement MultiReader struct
Implement a MultiReader (InStream) which sequentially read from the
provided readers (InStreams). Return IoError.EOF when all of the readers
are read.
* io: implement MultiWriter struct
Implement a MultiWriter (OutStream). The MultiWriter duplicates its
writes to all the provided writers (OutStream).
* io: implement TeeReader struct
Implement a TeeReader (InStream) which reads from a wrapped reader
(InStream) and writes data to the provided writer (OutStream).
* fix: change float format specifier in Object.to_format
Fix the float format specifier in Object.to_format. If there is a float
stored in a Object such as 3.14, it would be printed out as 3 because
the format specifier is %d but should be %g.
* fix: print nan in floatformat
Fix floatformat to print 'nan' if float is nan. Currently,
io::printn(float.nan) will produce 'inf' instead of 'nan'.
Fix a memory leak in HashMap.key_new_list(). The custom memory allocator
will not be used, since key_new_list() will call HashMap.copy_keys()
without passing the memory allocator along. Hence, HashMap.copy_keys()
will allocate on the heap and these memory blocks will not be freed.
To fix this, pass the custom allocator to HashMap.copy_keys(). Also,
since HashMap.key_new_list() is deprecated anyways, replace it by
HashMap.copy_keys().
Affected from this leak is Object.to_format() from
std::collection::object (for an ObjectInternalMap) which is used in the
JSON parser.
The tests for the JSON parser show the memory leak:
$ c3c compile-test test/unit/stdlib/encoding
$ valgrind --leak-check=yes ./testrun
==1454708==
==1454708== HEAP SUMMARY:
==1454708== in use at exit: 384 bytes in 8 blocks
==1454708== total heap usage: 69 allocs, 61 frees, 528,672 bytes allocated
==1454708==
==1454708== 48 bytes in 1 blocks are definitely lost in loss record 1 of 8
==1454708== at 0x48447A8: malloc (vg_replace_malloc.c:446)
==1454708== by 0x12CDBF: std.core.mem.allocator.LibcAllocator.acquire (libc_allocator.c3:42)
==1454708== by 0x1790FD: malloc_try (mem_allocator.c3:64)
==1454708== by 0x1790FD: alloc_array_try (mem_allocator.c3:286)
==1454708== by 0x1790FD: alloc_array (mem_allocator.c3:269)
==1454708== by 0x1790FD: copy_keys (hashmap.c3:310)
==1454708== by 0x1790FD: std_collections_map$String$p$std.collections.object.Object$.HashMap.key
==1454708== by 0x14D593: std.collections.object.Object.to_format (object.c3:53)
==1454708== by 0x164556: std.io.Formatter.print_with_function (formatter.c3:86)
==1454708== by 0x165B49: std.io.Formatter.out_str (formatter.c3:152)
==1454708== by 0x16E2B0: std.io.Formatter.vprintf (formatter.c3:456)
==1454708== by 0x12696B: std.core.dstring.DString.appendf (dstring.c3:532)
==1454708== by 0x124EA9: std.core.string.tformat (string.c3:79)
==1454708== by 0x113C79: json_test.test_string (json.c3:34)
==1454708== by 0x118AA1: std.core.runtime.run_tests (runtime.c3:227)
==1454708== by 0x1190B1: std.core.runtime.default_test_runner (runtime.c3:246)
==1454708==
[..snip..]
==1454708==
==1454708== LEAK SUMMARY:
==1454708== definitely lost: 384 bytes in 8 blocks
==1454708== indirectly lost: 0 bytes in 0 blocks
==1454708== possibly lost: 0 bytes in 0 blocks
==1454708== still reachable: 0 bytes in 0 blocks
==1454708== suppressed: 0 bytes in 0 blocks
==1454708==
==1454708== For lists of detected and suppressed errors, rerun with: -s
==1454708== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
Signed-off-by: Koni Marti <koni.marti@gmail.com>