diff options
-rw-r--r-- | Documentation/Doxyfile.in | 1 | ||||
-rw-r--r-- | src/libcamera/include/utils.h | 34 | ||||
-rw-r--r-- | src/libcamera/utils.cpp | 63 |
3 files changed, 98 insertions, 0 deletions
diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 1c46b04b..beeaf6d3 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -880,6 +880,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \ libcamera::BoundMethodStatic \ libcamera::SignalBase \ libcamera::*::Private \ + libcamera::*::details::* \ std::* # The EXAMPLE_PATH tag can be used to specify one or more files or directories diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h index e467eb21..080ea661 100644 --- a/src/libcamera/include/utils.h +++ b/src/libcamera/include/utils.h @@ -108,6 +108,40 @@ inline _hex hex<uint64_t>(uint64_t value, unsigned int width) size_t strlcpy(char *dst, const char *src, size_t size); +namespace details { + +class StringSplitter +{ +public: + StringSplitter(const std::string &str, const std::string &delim); + + class iterator + { + public: + iterator(const StringSplitter *ss, std::string::size_type pos); + + iterator &operator++(); + std::string operator*() const; + bool operator!=(const iterator &other) const; + + private: + const StringSplitter *ss_; + std::string::size_type pos_; + std::string::size_type next_; + }; + + iterator begin() const; + iterator end() const; + +private: + std::string str_; + std::string delim_; +}; + +} /* namespace details */ + +details::StringSplitter split(const std::string &str, const std::string &delim); + } /* namespace utils */ } /* namespace libcamera */ diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp index 4beffdab..94bbb883 100644 --- a/src/libcamera/utils.cpp +++ b/src/libcamera/utils.cpp @@ -199,6 +199,69 @@ size_t strlcpy(char *dst, const char *src, size_t size) return strlen(src); } +details::StringSplitter::StringSplitter(const std::string &str, const std::string &delim) + : str_(str), delim_(delim) +{ +} + +details::StringSplitter::iterator::iterator(const details::StringSplitter *ss, std::string::size_type pos) + : ss_(ss), pos_(pos) +{ + next_ = ss_->str_.find(ss_->delim_, pos_); +} + +details::StringSplitter::iterator &details::StringSplitter::iterator::operator++() +{ + pos_ = next_; + if (pos_ != std::string::npos) { + pos_ += ss_->delim_.length(); + next_ = ss_->str_.find(ss_->delim_, pos_); + } + + return *this; +} + +std::string details::StringSplitter::iterator::operator*() const +{ + std::string::size_type count; + count = next_ != std::string::npos ? next_ - pos_ : next_; + return ss_->str_.substr(pos_, count); +} + +bool details::StringSplitter::iterator::operator!=(const details::StringSplitter::iterator &other) const +{ + return pos_ != other.pos_; +} + +details::StringSplitter::iterator details::StringSplitter::begin() const +{ + return iterator(this, 0); +} + +details::StringSplitter::iterator details::StringSplitter::end() const +{ + return iterator(this, std::string::npos); +} + +/** + * \fn split(const std::string &str, const std::string &delim) + * \brief Split a string based on a delimiter + * \param[in] str The string to split + * \param[in] delim The delimiter string + * + * This function splits the string \a str into substrings based on the + * delimiter \a delim. It returns an object of unspecified type that can be + * used in a range-based for loop and yields the substrings in sequence. + * + * \return An object that can be used in a range-based for loop to iterate over + * the substrings + */ +details::StringSplitter split(const std::string &str, const std::string &delim) +{ + /** \todo Try to avoid copies of str and delim */ + return details::StringSplitter(str, delim); +} + } /* namespace utils */ } /* namespace libcamera */ |