| 89 | */ |
| 90 | template<class Enum, class Pred, class NameFunc> |
| 91 | Enum find_earliest_match(const string &spec, Enum begin, Enum end, |
| 92 | Pred pred, NameFunc namefunc) |
| 93 | { |
| 94 | Enum selected = end; |
| 95 | const size_t speclen = spec.length(); |
| 96 | size_t bestpos = string::npos; |
| 97 | size_t bestlen = string::npos; |
| 98 | for (size_t i = begin; i < (size_t) end; ++i) |
| 99 | { |
| 100 | const Enum curr = static_cast<Enum>(i); |
| 101 | |
| 102 | if (!pred(curr)) |
| 103 | continue; |
| 104 | |
| 105 | const string name = lowercase_string(namefunc(curr)); |
| 106 | const size_t pos = name.find(spec); |
| 107 | const size_t len = name.length(); |
| 108 | |
| 109 | if (pos < bestpos || pos == 0 && len < bestlen) |
| 110 | { |
| 111 | // Exit early if we found an exact match. |
| 112 | if (pos == 0 && len == speclen) |
| 113 | return curr; |
| 114 | |
| 115 | // npos is never less than bestpos, so the spec was found. |
| 116 | bestpos = pos; |
| 117 | if (pos == 0) |
| 118 | bestlen = len; |
| 119 | selected = curr; |
| 120 | } |
| 121 | } |
| 122 | return selected; |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Join together strings computed by a function applied to some elements |
no test coverage detected