Releases: biojppm/c4core
Releases · biojppm/c4core
Release list
Release 0.2.6
- PR#150: fix configure with cmake 4.
Release 0.2.5
- PR#149: Fix warnings from
-Wundef
Release 0.2.4
- Add header
c4/version.hpp:c4::version()c4::version_major()c4::version_minor()c4::version_patch()
- Update fast_float to 8.0.0
Release 0.2.3
- PR#147: Add utf utilities:
c4::first_non_bom()c4::get_bom()c4::skip_bom()
- PR#148: Improvements in dump.hpp:
- add traits class
c4::dump_directly<T>to enable selection of faster path where the intermediate dump buffer is not used for strings which can be directly dumped to the sink - improve
c4::format_dump_resume()to ensure the needed buffer size is still computed after buffer exhaustion
- add traits class
- PR#148: add
noexcepttoc4::overflows - PR#148: Add support for mips, mipsel, mips64, mips64el CPU architectures
- PR#148: Add support for sparc, sparc64 CPU architectures
- PR#148 and PR#12 cmake: Add support for loongarch, loongarch64 architectures
- PR#148: Improve CPU detection in armv4 and armv5
- PR#144: Include
<cstddef>forptrdiff_tusage - Minor improvements to doxygen documentation
Thanks
Release 0.2.2
- Amalgamate: fix include of
<charconv>(see rapidyaml#445). - Add
C4_MINGW(PR#139) - Annotate
c4::handle_error()with[[noreturn]](PR#137). - Add
bool from_chars(csubstr s, fmt::overflow_checked_<T> *wrapper). There was already a function receiving&wrapper, but*wrapperwas missing for use with generic code. - Ensure
posix_memalign()is never called with bad alignment values (PR#138) - Update fast_float to v6.1.1 (PR#136)
Thanks
Release 0.2.1
atod(): add missing assertion str.len > 0
Release 0.2.0
Breaking changes
- #PR101: As part of the
substrctor cleanup, theto_substr(char (&arr)[N])overload no longer decays tochar*inside. This changes calling code by now returning asubstrwith length equal toN-1instead ofstrlen(arr)as before:// longer than "foo", ie longer than {'f', 'o', 'o', '\0'}: char arr[] = "foo\0\0\0\0\0\0"; assert(strlen(arr) == 3); assert(sizeof(arr) == 9); // previously: assert(to_substr(arr).len == 3); // now: assert(to_substr(arr).len == 9); // the breaking change happens only with arrays: assert(to_substr((char*)ptr).len == 3); // as before
- PR#111 - Rename formatting overloads accepting
c4::append:catrs(append_t, ...) -> catrs_append(...)catseprs(append_t, ...) -> catseprs_append(...)formatrs(append_t, ...) -> formatrs_append(...)
New features
- #PR101: For
substrandcsubstr:- add simultaneous ctors from
char[]andchar*. Using SFINAE to narrow thechar*overload prevents it from overriding thechar[]overload. Thanks to @huangqinjin for the idea (see #97). - remove unneeded constructors of
csubstrfrom non-const chars. - to each single-argument ctor, add corresponding functions
to_csubstr()andto_substr()to enable clients coercing their types in generic code such asc4::cat()andc4::format(). - Add interop with
std::string_viewwhen the standard is at least C++17 (#PR101):- provided in the header
c4/std/string_view.hpp - similarly to existing interop headers, this is opt-in and requires explicit inclusion
- implemented:
to_csubstr()(sincestd::string_viewis not writeable, cannot provideto_csubstr())to_chars()(sincestd::string_viewis not writeable, cannot providefrom_chars())- comparison operators
- provided in the header
- add simultaneous ctors from
substr: split.first_not_of()and.last_not_of()into different overloads, removing the defaultedstartparameter:.first_not_of(T, start=0)->.first_not_of(T),.first_not_of(T, start).last_not_of(T, start=npos)->.first_not_of(T),.first_not_of(T, npos)
This may or may not result in a speedup.
- PR#105: Add macros in
c4/language.hppfor compile-time flow of exceptions:C4_EXCEPTIONS: defined when exceptions are enabledC4_IF_EXCEPTIONS(code_with_exc, code_without_exc): select statements for exceptions enabled/disabledC4_IF_EXCEPTIONS_(code_with_exc, code_without_exc): select code tokens for exceptions enabled/disabled
- PR#105: Add macros in
c4/language.hppfor compile-time flow of RTTI:C4_RTTI: defined when rtti is enabledC4_IF_RTTI(code_with_rtti, code_without_rtti): select statements for rtti enabled/disabledC4_IF_RTTI_(code_with_rtti, code_without_rtti): select code tokens for rtti enabled/disabled
- PR#109: Add partial support for XTENSA processors (missing implementation of
c4::aalloc()). See rapidyaml#358. - PR#119 Add LoongArch cpu support.
- Add compiler annotation helper macros:
C4_ASSUME,C4_NODISCARD,C4_DEPRECATED,C4_UNREACHABLE_AFTER_ERR
Fixes
- Fix #126: bad
Exceptionbeing used withC4_ERROR_THROWS_EXCEPTION. - PR#132:
- PR#121 - Fix compile on armv8 due to broken macro definition; see #122 and #94.
- PR#129 - Support android by enabling
aalloc()'s call tomemalign(), available for API 16+. - PR#115 - Refactor of
c4::blob/c4::cblob. Use SFINAE to invalidate some of the constructors. - PR#110/PR#107 - Update fast_float.
- PR#108 - Fix preprocessor concatenation of strings in
C4_NOT_IMPLEMENTED_MSG()andC4_NOT_IMPLEMENTED_IF_MSG(). - PR#106 - Fix include guard in the gcc 4.8 compatibility header, causing it to be missing from the amalgamated header. See also #125: there was no check for
__GNUC__being defined. - PR#123 - Ensure the gcc 4.8 compatibility header is installed (fixes #103).
- PR#105 - Fix existing throw in
c4/ext/sg14/inplace_function.h. Ensure tests run with exceptions disabled and RTTI disabled. Add examples of exceptional control flow withsetjmp()/std::longjmp(). - PR#104/PR#112 - Fix pedantic warnings in gcc, clang and MSVC
- PR#104 - Fix possible compile error when
__GNUC__is not defined - Inject explicit
#include <charconv>on the amalgamated header. The amalgamation tool was filtering all prior includes, thus causing a compilation error. Addresses rapidyaml#364. - PR#117: Windows: fix compilation with MSVC/clang++.
- Windows: add missing
C4CORE_EXPORTtoc4::base64_valid(),c4::base64_encode()andc4::base64_decode(). - rapidyaml#390 - fix
csubstr.first_real_span()when the exponent only has one digit (see fae7106)
Thanks
Release 0.1.11
Breaking changes
csubstr::operator==(std::nullptr_t)now strictly checks if the pointer is null and no longer looks at the length (rapidyaml#264):-bool csubstr::operator== (std::nullptr_t) const noexcept { return str == nullptr || len == 0; } -bool csubstr::operator!= (std::nullptr_t) const noexcept { return str != nullptr || len == 0; } +bool csubstr::operator== (std::nullptr_t) const noexcept { return str == nullptr; } +bool csubstr::operator!= (std::nullptr_t) const noexcept { return str != nullptr; }
to_substr(std::string &s)andto_csubstr(std::string const& s)now point at the first element when the string is empty (rapidyaml#264):This is OK because an empty- return c4::substr(!s.empty() ? &s[0] : nullptr, s.size()); + return c4::substr(&s[0], s.size());
std::stringis guaranteed to have storage, so callings[0]is safe.
New features
charconv.hpp: addedxtoa()floating-point overloads accepting precision and format (PR#88):size_t xtoa(substr s, float v, int precision, RealFormat_e formatting=FTOA_FLEX) noexcept; size_t xtoa(substr s, double v, int precision, RealFormat_e formatting=FTOA_FLEX) noexcept;
memory_util.hpp: addedipow()overloads for computing powers with integral exponents (PR#88).- Add
C4_NO_DEBUG_BREAKpreprocessor check to disable calls toc4::debug_break()(see rapidyaml#326)- The cmake project conditionally enables this macro if the cmake option
C4CORE_NO_DEBUG_BREAKis set toON.
- The cmake project conditionally enables this macro if the cmake option
Fixes
substr,to_chars(), charconv: ensurememcpy()is not called when the length is zero. Doing this is UB and enabled the optimizer to wreak havoc in the branches of calling code. See comments at rapidyaml#264 for an example and fix. See Raymond Chen's blog for an explanation.atof()andatod()(PR#88):- Always use the fastest implementation available:
std::from_chars()if available (C++17 or higher standard, with later compilers),fast_float::from_chars()otherwise. On Visual Studio,fast_float::from_chars()is preferred overstd::from_chars(). - If
std::from_chars()is not available andC4CORE_NO_FAST_FLOATis defined, then the fallback is based onsscanf(). - Ensure hexadecimal floats are accepted. The current fast_float implementation does not accept hexadecimal floats, so an hexfloat scanner was added.
- Always use the fastest implementation available:
- Likewise for
ftoa()anddtoa(). Prefer the fastest implementation available:std::to_chars()->snprintf().- Change the
FTOA_*enum values and type to save a function call when converting format. From now on, only the symbols of this enum can be relied on; the values or type will change depending on the selected implementation (std::to_chars()orsnprintf()) (PR#91).
- Change the
- Fix #84:
csubstr::compare(char): refactor to avoid false-positive warning from VS2022. csubstrmethods: addnoexceptand annotationsC4_PUREandC4_ALWAYS_INLINEcsubstr: addC4_RESTRICTto incoming string oncsubstr::compare()csubstr::first_real_span()(PR#89):- Refactor to fix number matching rules. Now fully valid for floating point numbers in decimal (eg
0.123/1.23e+01), hexadecimal (eg0x123.abc/0x1.23abcp+01), binary (eg0b101.10/0b1.0110p+01) and octal format (eg0o701.10/0o7.0110p+01) , with or without exponent or power, in lower or upper case. - Also, make the number parsing stateful to fix cases where repeated characters occur, (like e.g.
0.1.0or1.23e+e10) which are no longer reported as numbers (see biojppm/rapidyaml#291).
- Refactor to fix number matching rules. Now fully valid for floating point numbers in decimal (eg
csubstr::first_int_span(),csubstr::first_uint_span(): fix edge cases like e.g.0xzzwhich were wrongly reported as numbers.- Add fully qualified ARM detection macros:
- Improve linux and unix platform detection: detect both
__linuxand__linux__(PR#92).
Thanks
Release 0.1.10
Changes
Improved the performance of c4/charconv.hpp functions (PR#77):
- Added
digits_dec/hex/oct/bin(). - Optimized
write_dec/hex/oct/bin():- these functions now return immediately without entering the loop if the output buffer is smaller than respectively
digits_dec/hex/oct/bin(). This enables both:- writing every character in its final position without having to revert the string at the end
- the need to check the buffer size on appending every character.
write_dec()now writes two digits at once, thus halving the number of integer divisions.
- these functions now return immediately without entering the loop if the output buffer is smaller than respectively
- Added
write_dec/hex/oct/bin_unchecked(), which receive precomputeddigits_dec/hex/oct/bin(), thus speeding up the radixitoa()/utoa()overloads. - Added
xtoa()radix+digits overloads:size_t xtoa(substr s, T v, T radix)size_t xtoa(substr s, T v, T radix, size_t num_digits)
read_dec/hex/oct/bin(): these functions no longer allow an empty input buffer.- Use intrinsic functions
__builtin_clz()(gcc) /_BitScanReverse()(msvc) inc4::msb()and__builtin_ctz()(gcc) /_BitScanForward()(msvc) inc4::lsb()when they are available.msb()is used bydigits_hex()/digits_bin(). - Refactored the charconv tests to improve consistency and thoroughness.
- Improved the charconv benchmarks to ensure full consistency across benchmarks.
- Special thanks and kudos to @fargies for being attentive and pinpointing several issues throughout the PR!
- Finding the best approach involved writing a R&D benchmark for the several algorithm components. This benchmark is disabled by default, and can be enabled with the flag
C4CORE_BM_XTOA_RND. - With the changes from this PR, the charconv benchmark results show that on Linux/g++11.2, with integral types:
c4::to_chars()can be expected to be roughly...- ~40% to 2x faster than
std::to_chars() - ~10x-30x faster than
sprintf() - ~50x-100x faster than a naive
stringstream::operator<<()followed bystringstream::str()
- ~40% to 2x faster than
c4::from_chars()can be expected to be roughly...- ~10%-30% faster than
std::from_chars() - ~10x faster than
scanf() - ~30x-50x faster than a naive
stringstream::str()followed bystringstream::operator>>()
- ~10%-30% faster than
- Here are the results from the run:
Write throughput Read throughput write uint8_tMB/s read uint8_tMB/s c4::to_chars<u8>526.86 c4::from_chars<u8>163.06 std::to_chars<u8>379.03 std::from_chars<u8>154.85 std::sprintf<u8>20.49 std::scanf<u8>15.75 std::stringstream<u8>3.82 std::stringstream<u8>3.83 write int8_tMB/s read int8_tMB/s c4::to_chars<i8>599.98 c4::from_chars<i8>184.20 std::to_chars<i8>246.32 std::from_chars<i8>156.40 std::sprintf<i8>19.15 std::scanf<i8>16.44 std::stringstream<i8>3.83 std::stringstream<i8>3.89 write uint16_tMB/s read uint16_tMB/s c4::to_chars<u16>486.40 c4::from_chars<u16>349.48 std::to_chars<u16>454.24 std::from_chars<u16>319.13 std::sprintf<u16>38.74 std::scanf<u16>28.12 std::stringstream<u16>7.08 std::stringstream<u16>6.73 write int16_tMB/s read int16_tMB/s c4::to_chars<i16>507.44 c4::from_chars<i16>282.95 std::to_chars<i16>297.49 std::from_chars<i16>186.18 std::sprintf<i16>39.03 std::scanf<i16>28.45 std::stringstream<i16>6.98 std::stringstream<i16>6.49 write uint32_tMB/s read uint32_tMB/s c4::to_chars<u32>730.12 c4::from_chars<u32>463.95 std::to_chars<u32>514.76 std::from_chars<u32>329.42 std::sprintf<u32>71.19 std::scanf<u32>44.97 std::stringstream<u32>14.05 std::stringstream<u32>12.57 write int32_tMB/s read int32_tMB/s c4::to_chars<i32>618.76 c4::from_chars<i32>345.53 std::to_chars<i32>394.72 std::from_chars<i32>224.46 std::sprintf<i32>71.14 std::scanf<i32>43.49 std::stringstream<i32>13.91 std::stringstream<i32>12.03 write uint64_tMB/s read uint64_tMB/s c4::to_chars<u64>1118.87 c4::from_chars<u64>928.49 std::to_chars<u64>886.58 std::from_chars<u64>759.03 std::sprintf<u64>140.96 std::scanf<u64>91.60 std::stringstream<u64>28.01 std::stringstream<u64>25.00 write int64_tMB/s read int64_tMB/s c4::to_chars<i64>1198.78 c4::from_chars<i64>713.76 std::to_chars<i64>882.17 std::from_chars<i64>646.18 std::sprintf<i64>138.79 std::scanf<i64>90.07 std::stringstream<i64>27.62 std::stringstream<i64>25.12
If you feel suspicious about these bold claims, you can browse through c4core's CI benchmark results which will hopefully give these more substance.
New features
- Added
bool c4::overflows<T>(csubstr s)for detecting whether a string overflows a given integral type. See PR#78.- Also, added
c4::fmt::overflow_checked()(and the correspondingfrom_chars()overload) to enable a check for overflow before parsing from string:
c4::from_chars(str, &val); // no overflow check c4::from_chars(str, c4::fmt::overflow_checked(val)); // enable overflow check // as an example, the implementation looks like: template<class T> bool c4::from_chars(c4::csubstr str, c4::fmt::overflow_checked<T> oc) { if(overflows<T>(str)) return false; return c4::from_chars(str, oc.val); }
- Also, added
Fixes
- Fix missing endianess macro on windows arm/arm64 compilations PR #76
- Add missing
#definefor the include guard of the amalgamated header (see rapidyaml#246). - Fix CPU detection with ARMEL PR #86.
- Fix GCC version detection PR #87.
- Fix cmake#8:
SOVERSIONmissing from shared libraries. - Update fastfloat to 3.5.1.
Thanks
Release 0.1.9
Breaking changes
- fix #63: remove
c4/time.hppandc4/time.cppwhich prevented compilation in bare-metal mode (PR #64).
New features
- Added decoding of UTF codepoints:
c4::decode_code_point()(PR #65). - Experimental feature: add formatted-dumping facilities: using semantics like
c4::cat(),c4::catsep()andc4::format(), where the subject is not a string buffer but a dump callback accepting strings. This still requires a string buffer for serialization of non-string types, but the buffer's required size is now limited to the max serialized size of non-string arguments, in contrast to the requirement inc4::cat()et al which is the total serialized size of every argument. This enables very efficient and generic printf-like semantics with reuse of a single small buffer, and allows direct-printing to terminal or file (PR #67). This feature is still experimental and a minor amount of changes to the API is possible. - Added macro
C4_IF_CONSTEXPRresolving toif constexpr (...)if the c++ standard is at least c++17. csubstr: addcount(csubstr)overload.- Add support for RISC-V architectures (PR #69).
- Add support for bare-metal compilation (PR #64).
- gcc >= 4.8 support using polyfills for missing templates and features (PR #74 and PR #68).
Fixes
csubstr::operator==(std::nullptr_t)now returns true if either.str==nullptror.len==0.- Fix:
bool operator==(const char (&s)[N], csubstr)andoperator==(const char (&s)[N], substr). The template declaration for these functions had an extraconstwhich prevented these functions to participate in overload resolution, which in some cases resulted in calls resolving tooperator==(std::string const&, csubstr)if that header was visible (PR #64). - Fix
csubstr::last_not_of(): optional positional parameter was ignored PR #62. atof(),atod(),atox(),substr::is_real(),substr::first_real_span(): acceptinfinity,infandnanas valid reals PR #60.- Add missing export symbols PR #56, PR #57.
c4/substr_fwd.hpp: fix compilation failure in Xcode 12 and earlier, where the forward declaration forstd::allocatoris inside theinline namespace __1, unlike later versions PR #61, reported in rapidyaml#185.c4/error.hpp: fix compilation failure in debug mode in Xcode 12 and earlier:__clang_major__does not mean the same as in the common clang, and as a result the warning-Wgnu-inline-cpp-without-externdoes not exist there.