* Avoid undefined std::abs(INT_MIN) in integer_parser
When parsing a negative integer into a signed type whose minimum value
equals INTMAX_MIN (e.g. int64_t on typical platforms), integer_parser
computes the limit as std::abs(static_cast<intmax_t>(min())). Negating
INTMAX_MIN cannot be represented in intmax_t, so the std::abs call is
undefined behaviour. UBSan flags this on every negative int64_t parse,
including a trivial one like "-1":
runtime error: negation of -9223372036854775808 cannot be represented
in type 'long'; cast to an unsigned type to negate this value to itself
Build the same unsigned magnitude (|min| == max + 1 for two's-complement)
directly in the unsigned arithmetic type instead. For unsigned T the
expression wraps to 0, which matches the previous std::abs(0) value, so
behaviour for unsigned types is preserved.
* test: cover INT64_MIN parse and run parser tests under UBSan
* test: skip UBSan flags on Windows clang-cl/MinGW builds
* fix: Overwrite m_positional_set in parse_positional()
* feat: Allow append in positionals and fix discrepancy between m_positional and m_positional_set during replace
* feat: Add test for short options parsing
* fix: Update option parsing to allow = with short options
* fix: Fix custom option parsing in case of CXXOPTS_NO_REGEX
* Move `result` up and return it
This allows `gcc` to elide the copy in the return and keeps it from
warning with `-Wnvro` enabled.
* Remove harmful dtor definition
The definition of the dtor is not necessary and actually harmful since
the definition of a class's implicit copy constructor is deprecated if
that class has a user-declared constructor as of C++11. Compilers can
warn about this with `-Wdeprecated`.
---------
Co-authored-by: Christoph Weiss <weiss@wsoptics.de>
Fixes#290.
Checking for overflow should be done before integer overflows.
There are two checks:
(result > limit / base) is used for limits greater than rounded up to base,
e.g. for 65535 it will activate for 65540 and higher.
(result * base > limit - digit) is used for limit+1 to limit+n below
next base rounded number, e.g. 65536 up to 65539.