diff --git a/CMakeLists.txt b/CMakeLists.txt index f1b2dd3..6516439 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,8 +131,8 @@ set(META_APP_AUTHOR "Martchus") set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}") set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parser, IO and conversion utilities") set(META_VERSION_MAJOR 4) -set(META_VERSION_MINOR 12) -set(META_VERSION_PATCH 2) +set(META_VERSION_MINOR 13) +set(META_VERSION_PATCH 0) # find required 3rd party libraries include(3rdParty) diff --git a/conversion/stringconversion.h b/conversion/stringconversion.h index ce6e745..ae8bd09 100644 --- a/conversion/stringconversion.h +++ b/conversion/stringconversion.h @@ -158,6 +158,33 @@ Container splitString(const typename Container::value_type &string, const typena return res; } +/*! + * \brief Splits the given \a string (which might also be a string view) at the specified \a delimiter. + * \param string The string to be splitted. + * \param delimiter Specifies the delimiter. + * \param maxParts Specifies the maximal number of parts. Values less or equal zero indicate an unlimited number of parts. + * \tparam Container The STL-container used to return the parts. + * \returns Returns the parts. + * \remarks This is a simplified version of splitString() where emptyPartsRole is always EmptyPartsTreat::Keep. + */ +template > +Container splitStringSimple(const typename Container::value_type &string, const typename Container::value_type &delimiter, int maxParts = -1) +{ + --maxParts; + Container res; + for (typename Container::value_type::size_type i = 0, end = string.size(), delimPos; i < end; i = delimPos + delimiter.size()) { + delimPos = string.find(delimiter, i); + if (maxParts >= 0 && res.size() == static_cast(maxParts)) { + delimPos = Container::value_type::npos; + } + if (delimPos == Container::value_type::npos) { + delimPos = string.size(); + } + res.emplace_back(string.substr(i, delimPos - i)); + } + return res; +} + /*! * \brief Converts the specified \a multilineString to an array of lines. */ diff --git a/tests/conversiontests.cpp b/tests/conversiontests.cpp index 1bd44ce..9a6fa1e 100644 --- a/tests/conversiontests.cpp +++ b/tests/conversiontests.cpp @@ -290,6 +290,8 @@ void ConversionTests::testStringConversions() vector splitTestExpected({ "1", "2,3" }); vector splitTestActual = splitString>("1,2,3"s, ","s, EmptyPartsTreat::Keep, 2); CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual); + splitTestActual = splitStringSimple>("1,2,3"s, ","s, 2); + CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual); splitTestExpected = { "1", "2,3", "4,,5" }; splitTestActual = splitString>("1,2,,3,4,,5"s, ","s, EmptyPartsTreat::Merge, 3); CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual); @@ -297,6 +299,8 @@ void ConversionTests::testStringConversions() CPPUNIT_ASSERT_EQUAL("() (a) () (ab) (ABC) (s)"s, splitJoinTest); splitJoinTest = joinStrings(splitString>(",a,,ab,ABC,s"s, ","s, EmptyPartsTreat::Keep), " "s, true, "("s, ")"s); CPPUNIT_ASSERT_EQUAL("(a) (ab) (ABC) (s)"s, splitJoinTest); + splitJoinTest = joinStrings(splitStringSimple>(",a,,ab,ABC,s"s, ","s), " "s, true, "("s, ")"s); + CPPUNIT_ASSERT_EQUAL("(a) (ab) (ABC) (s)"s, splitJoinTest); splitJoinTest = joinStrings(splitString>(",a,,ab,ABC,s"s, ","s, EmptyPartsTreat::Omit), " "s, false, "("s, ")"s); CPPUNIT_ASSERT_EQUAL("(a) (ab) (ABC) (s)"s, splitJoinTest); splitJoinTest = joinStrings(splitString>(",a,,ab,ABC,s"s, ","s, EmptyPartsTreat::Merge), " "s, false, "("s, ")"s);