diff --git a/Jupiter/Readable_String.h b/Jupiter/Readable_String.h index 1f84008..28df9c5 100644 --- a/Jupiter/Readable_String.h +++ b/Jupiter/Readable_String.h @@ -88,6 +88,17 @@ namespace Jupiter size_t find(const T &value, size_t index = 0) const; size_t find(const Readable_String &in) const; + /** + * @brief Returns the index of the first element in the string with the specified value. + * Note: Case insensitive. Returns false for any type other than char and wchar_t. + * + * @param value Value of the element to search for. + * @param index Index of the match to return (i.e: 0 returns the first match). + * @return The index of an element if one is found, INVALID_INDEX otherwise. + */ + size_t findi(const T &value, size_t index = 0) const; + size_t findi(const Readable_String &in) const; + /** * @brief Returns the number of elements of the string which match the input string. * diff --git a/Jupiter/Readable_String_Imp.h b/Jupiter/Readable_String_Imp.h index f13669b..ae4cff8 100644 --- a/Jupiter/Readable_String_Imp.h +++ b/Jupiter/Readable_String_Imp.h @@ -68,8 +68,7 @@ template size_t Jupiter::Readable_String::find(const Jupiter::Rea if (in.size() == this->size()) return this->equals(in) ? 0 : Jupiter::INVALID_INDEX; if (in.size() == 0) return 0; - size_t j; - for (size_t i = 0; i != this->size() - in.size() + 1; i++) + for (size_t i = 0, j; i != this->size() - in.size() + 1; i++) { j = 0; while (this->get(i + j) == in.get(j)) @@ -78,6 +77,76 @@ template size_t Jupiter::Readable_String::find(const Jupiter::Rea return Jupiter::INVALID_INDEX; } +// findi + +template<> size_t inline Jupiter::Readable_String::findi(const char &value, size_t index) const +{ + const char upperValue = (const char) toupper(value); + for (size_t i = 0; i != this->size(); i++) + { + if (toupper(this->get(i)) == upperValue) + { + if (index == 0) return i; + else index--; + } + } + return Jupiter::INVALID_INDEX; +} + +template<> size_t inline Jupiter::Readable_String::findi(const wchar_t &value, size_t index) const +{ + const wchar_t upperValue = towupper(value); + for (size_t i = 0; i != this->size(); i++) + { + if (towupper(this->get(i)) == upperValue) + { + if (index == 0) return i; + else index--; + } + } + return Jupiter::INVALID_INDEX; +} + +template size_t Jupiter::Readable_String::findi(const T &value, size_t index) const +{ + return Jupiter::INVALID_INDEX; +} + +template<> size_t inline Jupiter::Readable_String::findi(const Jupiter::Readable_String &in) const +{ + if (in.size() > this->size()) return Jupiter::INVALID_INDEX; + if (in.size() == this->size()) return this->equalsi(in) ? 0 : Jupiter::INVALID_INDEX; + if (in.size() == 0) return 0; + + for (size_t i = 0, j; i != this->size() - in.size() + 1; i++) + { + j = 0; + while (toupper(this->get(i + j)) == toupper(in.get(j))) + if (++j == in.size()) return i; + } + return Jupiter::INVALID_INDEX; +} + +template<> size_t inline Jupiter::Readable_String::findi(const Jupiter::Readable_String &in) const +{ + if (in.size() > this->size()) return Jupiter::INVALID_INDEX; + if (in.size() == this->size()) return this->equalsi(in) ? 0 : Jupiter::INVALID_INDEX; + if (in.size() == 0) return 0; + + for (size_t i = 0, j; i != this->size() - in.size() + 1; i++) + { + j = 0; + while (towupper(this->get(i + j)) == towupper(in.get(j))) + if (++j == in.size()) return i; + } + return Jupiter::INVALID_INDEX; +} + +template size_t Jupiter::Readable_String::findi(const Jupiter::Readable_String &) const +{ + return Jupiter::INVALID_INDEX; +} + // span() template size_t Jupiter::Readable_String::span(const Jupiter::Readable_String &in) const