| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de> | ||
| 2 | // SPDX-License-Identifier: MIT | ||
| 3 | /*! | ||
| 4 | * \file | ||
| 5 | * \ingroup Common | ||
| 6 | * \brief Helper functions for casting types from and to strings. | ||
| 7 | */ | ||
| 8 | #ifndef GRIDFORMAT_COMMON_STRING_CONVERSION_HPP_ | ||
| 9 | #define GRIDFORMAT_COMMON_STRING_CONVERSION_HPP_ | ||
| 10 | |||
| 11 | #include <concepts> | ||
| 12 | #include <string> | ||
| 13 | #include <sstream> | ||
| 14 | #include <utility> | ||
| 15 | #include <locale> | ||
| 16 | #include <ranges> | ||
| 17 | #include <string_view> | ||
| 18 | #include <algorithm> | ||
| 19 | |||
| 20 | #include <gridformat/common/concepts.hpp> | ||
| 21 | #include <gridformat/common/exceptions.hpp> | ||
| 22 | |||
| 23 | namespace GridFormat { | ||
| 24 | |||
| 25 | //! \addtogroup Common | ||
| 26 | //! @{ | ||
| 27 | |||
| 28 | /*! | ||
| 29 | * \name String conversions | ||
| 30 | * Helper functions for obtaining a string representation of objects. | ||
| 31 | * Users may provide an overload for their types to be consumed by GridFormat. | ||
| 32 | */ | ||
| 33 | //!@{ | ||
| 34 | |||
| 35 | template<Concepts::Scalar T> | ||
| 36 | 661300 | inline std::string as_string(const T& t) { | |
| 37 | 661300 | return std::to_string(t); | |
| 38 | } | ||
| 39 | |||
| 40 | template<typename T> requires std::constructible_from<std::string, T> | ||
| 41 | 1180743 | inline std::string as_string(T&& t) { | |
| 42 |
1/2✓ Branch 2 taken 28942 times.
✗ Branch 3 not taken.
|
1296509 | return std::string{std::forward<T>(t)}; |
| 43 | } | ||
| 44 | |||
| 45 | 122046 | inline const std::string& as_string(const std::string& t) { | |
| 46 | 122046 | return t; | |
| 47 | } | ||
| 48 | |||
| 49 | template<std::ranges::range R> requires(!std::constructible_from<std::string, R>) | ||
| 50 | 62006 | inline std::string as_string(R&& range, std::string_view delimiter = " ") { | |
| 51 | 62006 | std::string result; | |
| 52 |
1/2✓ Branch 1 taken 38110 times.
✗ Branch 2 not taken.
|
247794 | std::ranges::for_each(range, [&] (const auto& entry) { |
| 53 | 178178 | result += delimiter; | |
| 54 |
17/45✓ Branch 1 taken 88325 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88325 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 22248 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 22248 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 5969 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 5961 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 25 taken 46428 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 46428 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✓ Branch 33 taken 13338 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 13338 times.
✗ Branch 37 not taken.
✓ Branch 41 taken 476 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 476 times.
✗ Branch 45 not taken.
✓ Branch 49 taken 1326 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1326 times.
✗ Branch 53 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
|
178178 | result += as_string(entry); |
| 55 | }); | ||
| 56 |
1/2✓ Branch 2 taken 38110 times.
✗ Branch 3 not taken.
|
62006 | result.erase(0, delimiter.size()); |
| 57 | 62006 | return result; | |
| 58 | ✗ | } | |
| 59 | |||
| 60 | template<Concepts::Scalar T> | ||
| 61 | 39229 | T from_string(const std::string& str) { | |
| 62 | if constexpr (std::is_same_v<T, char>) | ||
| 63 | return static_cast<T>(std::stoi(str)); | ||
| 64 | |||
| 65 |
1/2✓ Branch 1 taken 20429 times.
✗ Branch 2 not taken.
|
39229 | std::istringstream s(str); |
| 66 |
2/4✓ Branch 1 taken 20429 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20429 times.
✗ Branch 5 not taken.
|
39229 | s.imbue(std::locale::classic()); |
| 67 | |||
| 68 | T val; | ||
| 69 |
1/2✓ Branch 1 taken 20429 times.
✗ Branch 2 not taken.
|
39229 | s >> val; |
| 70 |
2/4✓ Branch 1 taken 20429 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 20429 times.
|
39229 | if (!s) |
| 71 | ✗ | throw ValueError("Could not extract value of requested type from '" + str + "'"); | |
| 72 | |||
| 73 | // make sure subsequent extraction fails | ||
| 74 | char dummy; | ||
| 75 |
1/2✓ Branch 1 taken 20429 times.
✗ Branch 2 not taken.
|
39229 | s >> dummy; |
| 76 |
8/11✓ Branch 1 taken 20428 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 20424 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 20425 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20424 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 20424 times.
|
39229 | if (!s.fail() || !s.eof()) |
| 77 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
2 | throw ValueError("Value extraction of requested type from string '" + str + "' unsuccessful"); |
| 78 | |||
| 79 | 39227 | return val; | |
| 80 | 39229 | } | |
| 81 | |||
| 82 | template<std::convertible_to<std::string> T> | ||
| 83 | 884571 | inline T from_string(const std::string& t) { | |
| 84 | 884571 | return T{t}; | |
| 85 | } | ||
| 86 | |||
| 87 | //! @} converter functions | ||
| 88 | //! @} Common group | ||
| 89 | |||
| 90 | } // namespace GridFormat | ||
| 91 | |||
| 92 | #endif // GRIDFORMAT_COMMON_STRING_CONVERSION_HPP_ | ||
| 93 |