find - Search for the first string \arg Str in the string. \return - The index of the first occurrence of \arg Str, or npos if not found.
| 131 | /// \return - The index of the first occurrence of \arg Str, or npos if not |
| 132 | /// found. |
| 133 | size_t StringRef::find(StringRef Str, size_t From) const { |
| 134 | if (From > Length) |
| 135 | return npos; |
| 136 | |
| 137 | const char *Start = Data + From; |
| 138 | size_t Size = Length - From; |
| 139 | |
| 140 | const char *Needle = Str.data(); |
| 141 | size_t N = Str.size(); |
| 142 | if (N == 0) |
| 143 | return From; |
| 144 | if (Size < N) |
| 145 | return npos; |
| 146 | if (N == 1) { |
| 147 | const char *Ptr = (const char *)::memchr(Start, Needle[0], Size); |
| 148 | return Ptr == nullptr ? npos : Ptr - Data; |
| 149 | } |
| 150 | |
| 151 | const char *Stop = Start + (Size - N + 1); |
| 152 | |
| 153 | // For short haystacks or unsupported needles fall back to the naive algorithm |
| 154 | if (Size < 16 || N > 255) { |
| 155 | do { |
| 156 | if (std::memcmp(Start, Needle, N) == 0) |
| 157 | return Start - Data; |
| 158 | ++Start; |
| 159 | } while (Start < Stop); |
| 160 | return npos; |
| 161 | } |
| 162 | |
| 163 | // Build the bad char heuristic table, with uint8_t to reduce cache thrashing. |
| 164 | uint8_t BadCharSkip[256]; |
| 165 | std::memset(BadCharSkip, N, 256); |
| 166 | for (unsigned i = 0; i != N-1; ++i) |
| 167 | BadCharSkip[(uint8_t)Str[i]] = N-1-i; |
| 168 | |
| 169 | do { |
| 170 | uint8_t Last = Start[N - 1]; |
| 171 | if (LLVM_UNLIKELY(Last == (uint8_t)Needle[N - 1])) |
| 172 | if (std::memcmp(Start, Needle, N - 1) == 0) |
| 173 | return Start - Data; |
| 174 | |
| 175 | // Otherwise skip the appropriate number of bytes. |
| 176 | Start += BadCharSkip[Last]; |
| 177 | } while (Start < Stop); |
| 178 | |
| 179 | return npos; |
| 180 | } |
| 181 | |
| 182 | size_t StringRef::find_lower(StringRef Str, size_t From) const { |
| 183 | StringRef This = substr(From); |