/* * This file is part of OpenTTD. * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . */ #ifndef STRING_FUNC_EXTRA_H #define STRING_FUNC_EXTRA_H #include "string_func.h" #include #include inline void StrMakeValidInPlace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) { if (str.empty()) return; char *buf = str.data(); str.resize(StrMakeValidInPlace(buf, buf + str.size(), settings) - buf); } template inline void ProcessLineByLine(char *buf, F line_functor) { char *p = buf; char *p2 = buf; /* Print output line by line */ for (; *p2 != '\0'; p2++) { if (*p2 == '\n') { *p2 = '\0'; line_functor(p); p = p2 + 1; } } if (p < p2) line_functor(p); } /* * Cut down version of std::from_chars, base is fixed at 10. * Returns true on success */ template inline bool IntFromChars(const char* first, const char* last, T& value) { static_assert(std::is_integral::value && !std::is_same::value, "T must be an integer"); bool negative = false; if (std::is_signed::value) { if (first != last && *first == '-') { first++; negative = true; } } T out = 0; const char * const start = first; while (first != last) { const char c = *first; if (c >= '0' && c <= '9') { #ifdef WITH_OVERFLOW_BUILTINS if (unlikely(__builtin_mul_overflow(out, 10, &out))) return false; if (unlikely(__builtin_add_overflow(out, c - '0', &out))) return false; #else if (unlikely(out > std::numeric_limits::max() / 10)) return false; out *= 10; if (unlikely(out > (std::numeric_limits::max() - (c - '0')))) return false; out += (c - '0'); #endif first++; } else { break; } } if (start == first) return false; if (std::is_signed::value) { #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4146) #endif value = negative ? -out : out; #ifdef _MSC_VER #pragma warning(pop) #endif } else { value = out; } return true; } #endif /* STRING_FUNC_EXTRA_H */