libcamera: utils: Add string join function
Add a utils::join() function to join elements of a container into a string, with a separator and an optional conversion function if the elements are not implicitly convertible to std::string. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
ebd0cae455
commit
79ce121b6b
3 changed files with 79 additions and 1 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -109,6 +110,49 @@ inline _hex hex<uint64_t>(uint64_t value, unsigned int width)
|
||||||
|
|
||||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||||
|
|
||||||
|
#ifndef __DOXYGEN__
|
||||||
|
template<typename Container, typename UnaryOp>
|
||||||
|
std::string join(const Container &items, const std::string &sep, UnaryOp op)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (typename Container::const_iterator it = std::begin(items);
|
||||||
|
it != std::end(items); ++it) {
|
||||||
|
if (!first)
|
||||||
|
ss << sep;
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
ss << op(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
std::string join(const Container &items, const std::string &sep)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (typename Container::const_iterator it = std::begin(items);
|
||||||
|
it != std::end(items); ++it) {
|
||||||
|
if (!first)
|
||||||
|
ss << sep;
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
ss << *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<typename Container, typename UnaryOp>
|
||||||
|
std::string join(const Container &items, const std::string &sep, UnaryOp op = nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
class StringSplitter
|
class StringSplitter
|
||||||
|
|
|
@ -297,6 +297,22 @@ details::StringSplitter::iterator details::StringSplitter::end() const
|
||||||
return iterator(this, std::string::npos);
|
return iterator(this, std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn template<typename Container, typename UnaryOp> \
|
||||||
|
* std::string utils::join(const Container &items, const std::string &sep, UnaryOp op)
|
||||||
|
* \brief Join elements of a container in a string with a separator
|
||||||
|
* \param[in] items The container
|
||||||
|
* \param[in] sep The separator to add between elements
|
||||||
|
* \param[in] op A function that converts individual elements to strings
|
||||||
|
*
|
||||||
|
* This function joins all elements in the \a items container into a string and
|
||||||
|
* returns it. The \a sep separator is added between elements. If the container
|
||||||
|
* elements are not implicitly convertible to std::string, the \a op function
|
||||||
|
* shall be provided to perform conversion of elements to std::string.
|
||||||
|
*
|
||||||
|
* \return A string that concatenates all elements in the container
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn split(const std::string &str, const std::string &delim)
|
* \fn split(const std::string &str, const std::string &delim)
|
||||||
* \brief Split a string based on a delimiter
|
* \brief Split a string based on a delimiter
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <libcamera/geometry.h>
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ protected:
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* utils::split() test. */
|
/* utils::join() and utils::split() test. */
|
||||||
std::vector<std::string> elements = {
|
std::vector<std::string> elements = {
|
||||||
"/bin",
|
"/bin",
|
||||||
"/usr/bin",
|
"/usr/bin",
|
||||||
|
@ -111,6 +113,11 @@ protected:
|
||||||
for (const auto &element : elements)
|
for (const auto &element : elements)
|
||||||
path += (path.empty() ? "" : ":") + element;
|
path += (path.empty() ? "" : ":") + element;
|
||||||
|
|
||||||
|
if (path != utils::join(elements, ":")) {
|
||||||
|
cerr << "utils::join() test failed" << endl;
|
||||||
|
return TestFail;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> dirs;
|
std::vector<std::string> dirs;
|
||||||
|
|
||||||
for (const auto &dir : utils::split(path, ":"))
|
for (const auto &dir : utils::split(path, ":"))
|
||||||
|
@ -121,6 +128,17 @@ protected:
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* utils::join() with conversion function test. */
|
||||||
|
std::vector<Size> sizes = { { 0, 0 }, { 100, 100 } };
|
||||||
|
s = utils::join(sizes, "/", [](const Size &size) {
|
||||||
|
return size.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (s != "0x0/100x100") {
|
||||||
|
cerr << "utils::join() with conversion test failed" << endl;
|
||||||
|
return TestFail;
|
||||||
|
}
|
||||||
|
|
||||||
/* utils::dirname() tests. */
|
/* utils::dirname() tests. */
|
||||||
if (TestPass != testDirname())
|
if (TestPass != testDirname())
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue