| 59 | * */ |
| 60 | template <typename T, size_t N> |
| 61 | std::array<T, N> convertStringToArray(const std::string& inputString, |
| 62 | bool exactLength = true, |
| 63 | bool skipEmpty = true, |
| 64 | char delimiter = ' ') { |
| 65 | auto result = std::array<T, N>(); |
| 66 | if (inputString.empty()) { |
| 67 | if (exactLength && N > 0) { |
| 68 | throw std::runtime_error( |
| 69 | std::string("Insufficient number of elements in array. Given: 0. Required: ") + |
| 70 | std::to_string(N) + std::string(".")); |
| 71 | } else { |
| 72 | return result; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | auto convert = [&inputString](size_t begin, size_t end) { |
| 77 | size_t count = end - begin; |
| 78 | std::string word = inputString.substr(begin, count); |
| 79 | if constexpr (std::is_integral<T>::value) { |
| 80 | return std::stoi(word); |
| 81 | } else if constexpr (std::is_floating_point<T>::value) { |
| 82 | return std::stod(word); |
| 83 | } else { |
| 84 | return static_cast<T>(word); |
| 85 | } |
| 86 | }; |
| 87 | |
| 88 | size_t begin = 0; |
| 89 | size_t wordCount = 0; |
| 90 | enum class State { Word, Delimiter }; |
| 91 | State s = inputString.at(0) == delimiter ? State::Delimiter : State::Word; |
| 92 | |
| 93 | // iterate over all words. We need to start at zero here: suppose we had ";;;" with delimiter ';'. |
| 94 | // when !skipEmpty, this denotes an array with four elements; the first three are found with this |
| 95 | // loop here. |
| 96 | for (size_t i = 0; i < inputString.size(); i++) { |
| 97 | if (inputString.at(i) == delimiter) { |
| 98 | // either we have a word, or two subsequent delimiters |
| 99 | if (s == State::Word || !skipEmpty) { |
| 100 | result.at(wordCount) = convert(begin, i); |
| 101 | ++wordCount; |
| 102 | if (wordCount >= N) { |
| 103 | break; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | // exclude the delimiter, hence i+1 |
| 108 | begin = i + 1; |
| 109 | s = State::Delimiter; |
| 110 | } else { |
| 111 | s = State::Word; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | // handle rest. Note that if a line ends with a delimiter, we consider the last element to be an |
| 116 | // empty one again. |
| 117 | if ((s == State::Word || !skipEmpty) && wordCount < N) { |
| 118 | result.at(wordCount) = convert(begin, inputString.size()); |