libcamera: utils: Add string splitter utility function
Add a utils::split() function that splits a string for the purpose of iterating over substrings. It returns an object of unspecified type that can be used in range-based for loops. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
b3dbccd328
commit
31a05b70aa
3 changed files with 98 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue