mirror of
https://github.com/red0124/ssp.git
synced 2025-12-14 21:59:55 +01:00
Write additional parser tests, update some of the existing tests to work with throw_on_error
This commit is contained in:
@@ -19,6 +19,12 @@ inline void assert_string_error_defined() {
|
||||
"'string_error' needs to be enabled to use 'error_msg'");
|
||||
}
|
||||
|
||||
template <bool ThrowOnError>
|
||||
inline void assert_throw_on_error_not_defined() {
|
||||
static_assert(!ThrowOnError, "cannot handle errors manually if "
|
||||
"'throw_on_error' is enabled");
|
||||
}
|
||||
|
||||
#if __unix__
|
||||
inline ssize_t get_line(char** lineptr, size_t* n, FILE* stream) {
|
||||
return getline(lineptr, n, stream);
|
||||
|
||||
@@ -167,6 +167,7 @@ inline bool sub_overflow(long long& result, long long operand) {
|
||||
return __builtin_ssubll_overflow(result, operand, &result);
|
||||
}
|
||||
|
||||
// Note: sub_overflow function should be unreachable for unsigned values
|
||||
template <>
|
||||
inline bool sub_overflow(unsigned int& result, unsigned int operand) {
|
||||
return __builtin_usub_overflow(result, operand, &result);
|
||||
@@ -184,8 +185,8 @@ inline bool sub_overflow(unsigned long long& result,
|
||||
}
|
||||
|
||||
template <typename T, typename F>
|
||||
bool shift_and_add_overflow(T& value, T digit, F add_last_digit_owerflow) {
|
||||
if (mul_overflow<T>(value, 10) || add_last_digit_owerflow(value, digit)) {
|
||||
bool shift_and_add_overflow(T& value, T digit, F add_last_digit_overflow) {
|
||||
if (mul_overflow<T>(value, 10) || add_last_digit_overflow(value, digit)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -223,17 +224,17 @@ std::enable_if_t<std::is_integral_v<T>, std::optional<T>> to_num(
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__) || defined(__GUNG__)) && \
|
||||
!defined(MINGW32_CLANG)
|
||||
auto add_last_digit_owerflow =
|
||||
auto add_last_digit_overflow =
|
||||
(is_negative) ? sub_overflow<T> : add_overflow<T>;
|
||||
#else
|
||||
auto add_last_digit_owerflow = is_negative;
|
||||
auto add_last_digit_overflow = is_negative;
|
||||
#endif
|
||||
|
||||
T value = 0;
|
||||
for (auto i = begin; i != end; ++i) {
|
||||
if (auto digit = from_char(*i);
|
||||
!digit || shift_and_add_overflow<T>(value, digit.value(),
|
||||
add_last_digit_owerflow)) {
|
||||
add_last_digit_overflow)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ public:
|
||||
|
||||
template <typename Fun>
|
||||
auto on_error(Fun&& fun) {
|
||||
// TODO disable these if throw_on_error
|
||||
assert_throw_on_error_not_defined<throw_on_error>();
|
||||
if (!parser_.valid()) {
|
||||
if constexpr (std::is_invocable_v<Fun>) {
|
||||
fun();
|
||||
@@ -355,6 +355,7 @@ public:
|
||||
template <typename... Ts, typename Fun = none>
|
||||
composite<std::optional<no_void_validator_tup_t<Ts...>>> try_next(
|
||||
Fun&& fun = none{}) {
|
||||
assert_throw_on_error_not_defined<throw_on_error>();
|
||||
using Ret = no_void_validator_tup_t<Ts...>;
|
||||
return try_invoke_and_make_composite<
|
||||
std::optional<Ret>>(get_next<Ts...>(), std::forward<Fun>(fun));
|
||||
@@ -364,6 +365,7 @@ public:
|
||||
// tuple
|
||||
template <typename T, typename... Ts, typename Fun = none>
|
||||
composite<std::optional<T>> try_object(Fun&& fun = none{}) {
|
||||
assert_throw_on_error_not_defined<throw_on_error>();
|
||||
return try_invoke_and_make_composite<
|
||||
std::optional<T>>(get_object<T, Ts...>(), std::forward<Fun>(fun));
|
||||
}
|
||||
@@ -742,7 +744,6 @@ private:
|
||||
return size;
|
||||
}
|
||||
|
||||
// TODO check why multiline fields result in additional allocations
|
||||
void realloc_concat(char*& first, size_t& first_size,
|
||||
const char* const second, size_t second_size) {
|
||||
// TODO make buffer_size an argument
|
||||
|
||||
Reference in New Issue
Block a user