Last active
March 9, 2016 11:34
-
-
Save yuiAs/20b986bb30cf372079b4 to your computer and use it in GitHub Desktop.
Expand number list with ranges
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| template <typename T> | |
| std::deque<T> expand_ranges(const std::string& src, size_t limit) | |
| { | |
| std::deque<T> r; | |
| // 現状の parseStringToでは結局分割した std::stringが必要なので先に splitでバラしておく | |
| auto a = split(src, ','); | |
| for (auto it = a.cbegin(); ((it != a.cend()) && (r.size() <= limit)); ++it) { | |
| T v1; | |
| if (parseStringTo<T>(v1, *it) == it->size()) { | |
| auto w = std::lower_bound(r.cbegin(), r.cend(), v1); | |
| if ((w == r.cend()) || (*w != v1)) { | |
| r.insert(w, v1); | |
| } | |
| } else { | |
| // NOTE: 次の文字を直接見るというのは怖いのでやらない | |
| std::string::size_type p0 = 0; | |
| while (p0 < it->size()) { | |
| std::string::size_type p1 = it->find_first_of('-', p0); | |
| // p0==p1は負数の '-' | |
| if (p0 == p1) { | |
| std::string::size_type p2 = p1 + 1; | |
| std::string::size_type p3 = it->find_first_of('-', p2); | |
| if (p3 == std::string::npos) { | |
| // これは範囲指定がおかしい (終点指定がない) | |
| std::cerr << "!not found range end: " << *it << std::endl; | |
| break; | |
| } else { | |
| // lhs | |
| if (parseStringTo<T>(v1, it->substr(p0, (p3 - p0))) != (p3 - p0)) { | |
| // 文字列 -> 数値でなんらかのエラーが発生してるので継続しない | |
| std::cerr << "!unknown: " << *it << std::endl; | |
| break; | |
| } else { | |
| p0 = p3 + 1; | |
| } | |
| } | |
| } else { | |
| if (p1 == std::string::npos) { | |
| // 最低でも +1して回すためないとは思うけど一応終端チェック | |
| break; | |
| } else { | |
| // lhs | |
| size_t length = p1 - p0; | |
| if (parseStringTo<T>(v1, it->substr(p0, length)) != length) { | |
| // 文字列 -> 数値でなんらかのエラーが発生してるので継続しない | |
| std::cerr << "!unknown2: " << *it << std::endl; | |
| break; | |
| } else { | |
| p0 = p1 + 1; | |
| } | |
| } | |
| } | |
| // rhs | |
| if (p0 < it->size()) { | |
| T v2; | |
| size_t length = it->size() - p0 + 1; | |
| if (parseStringTo<T>(v2, it->substr(p0)) != length) { | |
| if (v2 < v1) { | |
| std::swap(v1, v2); | |
| } | |
| for (auto i = v1; ((i <= v2) && (r.size() <= limit)); ++i) { | |
| auto w = std::lower_bound(r.cbegin(), r.cend(), i); | |
| if ((w == r.cend()) || (*w != i)) { | |
| r.insert(w, i); | |
| } | |
| } | |
| } else { | |
| // 文字列 -> 数値でなんらかのエラーが発生してるので継続しない | |
| std::cerr << "!unknown3: " << *it << std::endl; | |
| } | |
| } else { | |
| // これは範囲指定がおかしい (終点指定がない) | |
| std::cerr << "!not found range end: " << *it << std::endl; | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| return r; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment