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 | 655236 | inline std::string as_string(const T& t) { | |
37 | 655236 | return std::to_string(t); | |
38 | } | ||
39 | |||
40 | template<typename T> requires std::constructible_from<std::string, T> | ||
41 | 1170849 | inline std::string as_string(T&& t) { | |
42 |
1/2✓ Branch 2 taken 28651 times.
✗ Branch 3 not taken.
|
1285451 | return std::string{std::forward<T>(t)}; |
43 | } | ||
44 | |||
45 | 120707 | inline const std::string& as_string(const std::string& t) { | |
46 | 120707 | return t; | |
47 | } | ||
48 | |||
49 | template<std::ranges::range R> requires(!std::constructible_from<std::string, R>) | ||
50 | 60986 | inline std::string as_string(R&& range, std::string_view delimiter = " ") { | |
51 | 60986 | std::string result; | |
52 |
1/2✓ Branch 1 taken 37600 times.
✗ Branch 2 not taken.
|
243714 | std::ranges::for_each(range, [&] (const auto& entry) { |
53 | 176648 | result += delimiter; | |
54 |
13/45✓ Branch 1 taken 88699 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88699 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 23761 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 23761 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 8060 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 8052 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 25 taken 41600 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 41600 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✓ Branch 33 taken 14460 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 14460 times.
✗ Branch 37 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ 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.
|
176648 | result += as_string(entry); |
55 | }); | ||
56 |
1/2✓ Branch 2 taken 37600 times.
✗ Branch 3 not taken.
|
60986 | result.erase(0, delimiter.size()); |
57 | 60986 | return result; | |
58 | ✗ | } | |
59 | |||
60 | template<Concepts::Scalar T> | ||
61 | 39057 | 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 20257 times.
✗ Branch 2 not taken.
|
39057 | std::istringstream s(str); |
66 |
2/4✓ Branch 1 taken 20257 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20257 times.
✗ Branch 5 not taken.
|
39057 | s.imbue(std::locale::classic()); |
67 | |||
68 | T val; | ||
69 |
1/2✓ Branch 1 taken 20257 times.
✗ Branch 2 not taken.
|
39057 | s >> val; |
70 |
2/4✓ Branch 1 taken 20257 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 20257 times.
|
39057 | 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 20257 times.
✗ Branch 2 not taken.
|
39057 | s >> dummy; |
76 |
8/11✓ Branch 1 taken 20256 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 20252 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 20253 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20252 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 20252 times.
|
39057 | 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 | 39055 | return val; | |
80 | 39057 | } | |
81 | |||
82 | template<std::convertible_to<std::string> T> | ||
83 | 876382 | inline T from_string(const std::string& t) { | |
84 | 876382 | return T{t}; | |
85 | } | ||
86 | |||
87 | //! @} converter functions | ||
88 | //! @} Common group | ||
89 | |||
90 | } // namespace GridFormat | ||
91 | |||
92 | #endif // GRIDFORMAT_COMMON_STRING_CONVERSION_HPP_ | ||
93 |