diff options
| author | Martin Hořeňovský | 2022-10-20 15:06:26 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2022-10-21 10:53:50 +0200 |
| commit | d7341b5dc198d8b66cb0b70bb54f5655c6a85ffe (patch) | |
| tree | 1d26b338e7f0abe0020f1ce141fbe3410c3ff285 /src/catch2/internal | |
| parent | 38d926090a9f14a9776d9fd5bda2290be3df6cdb (diff) | |
| download | catch3-d7341b5dc198d8b66cb0b70bb54f5655c6a85ffe.tar.gz | |
Add parseUInt utility function
There is an increasing number of places where Catch2 wants to parse
strings into numbers, but being stuck in C++14 world, we do not
have good stdlib facilities to do this (`strtoul` and `stoul`
are both bad).
Diffstat (limited to 'src/catch2/internal')
| -rw-r--r-- | src/catch2/internal/catch_parse_numbers.cpp | 49 | ||||
| -rw-r--r-- | src/catch2/internal/catch_parse_numbers.hpp | 26 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/catch2/internal/catch_parse_numbers.cpp b/src/catch2/internal/catch_parse_numbers.cpp new file mode 100644 index 00000000..05649046 --- /dev/null +++ b/src/catch2/internal/catch_parse_numbers.cpp @@ -0,0 +1,49 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include <catch2/internal/catch_parse_numbers.hpp> + +#include <catch2/internal/catch_compiler_capabilities.hpp> +#include <catch2/internal/catch_string_manip.hpp> + +#include <limits> + +namespace Catch { + + Optional<unsigned int> parseUInt(std::string const& input, int base) { + auto trimmed = trim( input ); + // std::stoull is annoying and accepts numbers starting with '-', + // it just negates them into unsigned int + if ( trimmed.empty() || trimmed[0] == '-' ) { + return {}; + } + + CATCH_TRY { + size_t pos = 0; + const auto ret = std::stoull( trimmed, &pos, base ); + + // We did not consume the whole input, so there is an issue + // This can be bunch of different stuff, like multiple numbers + // in the input, or invalid digits/characters and so on. Either + // way, we do not want to return the partially parsed result. + if ( pos != trimmed.size() ) { + return {}; + } + // Too large + if ( ret > std::numeric_limits<unsigned int>::max() ) { + return {}; + } + return static_cast<unsigned int>(ret); + } CATCH_CATCH_ANON( std::exception const& ) { + // There was a larger issue with the input, e.g. the parsed + // number would be too large to fit within ull. + return {}; + } + } + +} // namespace Catch diff --git a/src/catch2/internal/catch_parse_numbers.hpp b/src/catch2/internal/catch_parse_numbers.hpp new file mode 100644 index 00000000..941c0f24 --- /dev/null +++ b/src/catch2/internal/catch_parse_numbers.hpp @@ -0,0 +1,26 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_PARSE_NUMBERS_HPP_INCLUDED +#define CATCH_PARSE_NUMBERS_HPP_INCLUDED + +#include <catch2/internal/catch_optional.hpp> + +#include <string> + +namespace Catch { + + /** + * Parses unsigned int from the input, using provided base + * + * Effectively a wrapper around std::stoul but with better error checking + * e.g. "-1" is rejected, instead of being parsed as UINT_MAX. + */ + Optional<unsigned int> parseUInt(std::string const& input, int base = 10); +} + +#endif // CATCH_PARSE_NUMBERS_HPP_INCLUDED |