Improve parameter-passing in some string conversion functions
* Allow using a range as input of joinStrings() * Use `std::string_view` instead of `const std::string &` to pass read-only parameters to joinStrings() and splitString*() to avoid constructing an `std::string` from `const char *` parameters * Use auto for return types of toMultiline() and toArrayOfLines() * Does not affect BC because those are template functions * Should not affect source compatibility; at least uses in my main projects seem to be unaffected
This commit is contained in:
parent
6968716d5c
commit
cc63c8c250
|
@ -18,6 +18,10 @@
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if __cplusplus >= 201709
|
||||||
|
#include <ranges>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace CppUtilities {
|
namespace CppUtilities {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -59,6 +63,20 @@ CPP_UTILITIES_EXPORT WideStringData convertMultiByteToWide(const std::string &in
|
||||||
|
|
||||||
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
|
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
|
||||||
|
|
||||||
|
/// \cond
|
||||||
|
namespace Detail {
|
||||||
|
#if __cplusplus >= 201709
|
||||||
|
template <class Container>
|
||||||
|
using ContainerValueType = typename std::conditional_t<std::ranges::range<Container>,
|
||||||
|
std::iterator_traits<std::remove_cvref_t<std::ranges::iterator_t<Container>>>, Container>::value_type;
|
||||||
|
#else
|
||||||
|
template <class Container> using ContainerValueType = typename Container::value_type;
|
||||||
|
#endif
|
||||||
|
template <class Container> using DefaultReturnTypeForContainer = ContainerValueType<Container>;
|
||||||
|
template <class Container> using StringParamForContainer = std::basic_string_view<typename ContainerValueType<Container>::value_type>;
|
||||||
|
} // namespace Detail
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Joins the given \a strings using the specified \a delimiter.
|
* \brief Joins the given \a strings using the specified \a delimiter.
|
||||||
*
|
*
|
||||||
|
@ -69,13 +87,14 @@ CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar
|
||||||
* \param omitEmpty Indicates whether empty part should be omitted.
|
* \param omitEmpty Indicates whether empty part should be omitted.
|
||||||
* \param leftClosure Specifies a string to be inserted before each string (empty string by default).
|
* \param leftClosure Specifies a string to be inserted before each string (empty string by default).
|
||||||
* \param rightClosure Specifies a string to be appendend after each string (empty string by default).
|
* \param rightClosure Specifies a string to be appendend after each string (empty string by default).
|
||||||
* \tparam Container The STL-container used to provide the \a strings.
|
* \tparam Container Container The STL-container used to provide the \a strings.
|
||||||
|
* \tparam ReturnType Type to store the result; defaults to the container's element type.
|
||||||
* \returns Returns the joined string.
|
* \returns Returns the joined string.
|
||||||
*/
|
*/
|
||||||
template <class Container = std::initializer_list<std::string>, class ReturnType = typename Container::value_type>
|
template <class Container = std::initializer_list<std::string>, class ReturnType = Detail::DefaultReturnTypeForContainer<Container>>
|
||||||
ReturnType joinStrings(const Container &strings, const typename Container::value_type &delimiter = typename Container::value_type(),
|
ReturnType joinStrings(const Container &strings, Detail::StringParamForContainer<Container> delimiter = Detail::StringParamForContainer<Container>(),
|
||||||
bool omitEmpty = false, const typename Container::value_type &leftClosure = typename Container::value_type(),
|
bool omitEmpty = false, Detail::StringParamForContainer<Container> leftClosure = Detail::StringParamForContainer<Container>(),
|
||||||
const typename Container::value_type &rightClosure = typename Container::value_type())
|
Detail::StringParamForContainer<Container> rightClosure = Detail::StringParamForContainer<Container>())
|
||||||
{
|
{
|
||||||
ReturnType res;
|
ReturnType res;
|
||||||
if (!strings.size()) {
|
if (!strings.size()) {
|
||||||
|
@ -111,7 +130,7 @@ ReturnType joinStrings(const Container &strings, const typename Container::value
|
||||||
/*!
|
/*!
|
||||||
* \brief Converts the specified \a arrayOfLines to a multiline string.
|
* \brief Converts the specified \a arrayOfLines to a multiline string.
|
||||||
*/
|
*/
|
||||||
template <class Container = std::initializer_list<std::string>> inline std::vector<std::string> toMultiline(const Container &arrayOfLines)
|
template <class Container = std::initializer_list<std::string>> inline auto toMultiline(const Container &arrayOfLines)
|
||||||
{
|
{
|
||||||
return joinStrings(arrayOfLines, "\n", false);
|
return joinStrings(arrayOfLines, "\n", false);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +154,7 @@ enum class EmptyPartsTreat {
|
||||||
* \returns Returns the parts.
|
* \returns Returns the parts.
|
||||||
*/
|
*/
|
||||||
template <class Container = std::list<std::string>>
|
template <class Container = std::list<std::string>>
|
||||||
Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter,
|
Container splitString(Detail::StringParamForContainer<Container> string, Detail::StringParamForContainer<Container> delimiter,
|
||||||
EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1)
|
EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1)
|
||||||
{
|
{
|
||||||
--maxParts;
|
--maxParts;
|
||||||
|
@ -183,7 +202,7 @@ Container splitString(const typename Container::value_type &string, const typena
|
||||||
* \remarks This is a simplified version of splitString() where emptyPartsRole is always EmptyPartsTreat::Keep.
|
* \remarks This is a simplified version of splitString() where emptyPartsRole is always EmptyPartsTreat::Keep.
|
||||||
*/
|
*/
|
||||||
template <class Container = std::list<std::string>>
|
template <class Container = std::list<std::string>>
|
||||||
Container splitStringSimple(const typename Container::value_type &string, const typename Container::value_type &delimiter, int maxParts = -1)
|
Container splitStringSimple(Detail::StringParamForContainer<Container> string, Detail::StringParamForContainer<Container> delimiter, int maxParts = -1)
|
||||||
{
|
{
|
||||||
--maxParts;
|
--maxParts;
|
||||||
Container res;
|
Container res;
|
||||||
|
@ -211,7 +230,7 @@ Container splitStringSimple(const typename Container::value_type &string, const
|
||||||
/*!
|
/*!
|
||||||
* \brief Converts the specified \a multilineString to an array of lines.
|
* \brief Converts the specified \a multilineString to an array of lines.
|
||||||
*/
|
*/
|
||||||
template <class Container = std::vector<std::string>> inline std::vector<std::string> toArrayOfLines(const std::string &multilineString)
|
template <class Container = std::vector<std::string>> inline auto toArrayOfLines(const std::string &multilineString)
|
||||||
{
|
{
|
||||||
return splitString<Container>(multilineString, "\n", EmptyPartsTreat::Keep);
|
return splitString<Container>(multilineString, "\n", EmptyPartsTreat::Keep);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue