Fix splitString()/splitStringSimple() for case of empty trailing part

charconv
Martchus 1 year ago
parent 0fb533ffc5
commit f549285fde
  1. 2
      CMakeLists.txt
  2. 20
      conversion/stringconversion.h
  3. 5
      tests/conversiontests.cpp

@ -114,7 +114,7 @@ set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parse
set(META_FEATURES_FOR_COMPILER_DETECTION_HEADER cxx_thread_local)
set(META_VERSION_MAJOR 5)
set(META_VERSION_MINOR 10)
set(META_VERSION_PATCH 2)
set(META_VERSION_PATCH 3)
# find required 3rd party libraries
include(3rdParty)

@ -161,7 +161,8 @@ Container splitString(Detail::StringParamForContainer<Container> string, Detail:
Container res;
typename Container::value_type *last = nullptr;
bool merge = false;
for (typename Container::value_type::size_type i = 0, end = string.size(), delimPos; i < end; i = delimPos + delimiter.size()) {
typename Container::value_type::size_type i = 0, end = string.size();
for (typename Container::value_type::size_type delimPos; i < end; i = delimPos + delimiter.size()) {
delimPos = string.find(delimiter, i);
if (!merge && maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) {
if (delimPos == i && emptyPartsRole == EmptyPartsTreat::Merge) {
@ -189,6 +190,9 @@ Container splitString(Detail::StringParamForContainer<Container> string, Detail:
}
}
}
if (i == end && emptyPartsRole == EmptyPartsTreat::Keep) {
res.emplace_back();
}
return res;
}
@ -207,7 +211,8 @@ Container splitStringSimple(
{
--maxParts;
Container res;
for (typename Container::value_type::size_type i = 0, end = string.size(), delimPos; i < end; i = delimPos + delimiter.size()) {
typename Container::value_type::size_type i = 0, end = string.size();
for (typename Container::value_type::size_type delimPos; i < end; i = delimPos + delimiter.size()) {
delimPos = string.find(delimiter, i);
if (maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) {
delimPos = Container::value_type::npos;
@ -223,6 +228,17 @@ Container splitStringSimple(
} else {
res.emplace(string.data() + i, delimPos - i);
}
#endif
}
if (i == end) {
#if __cplusplus >= 201709
if constexpr (requires { res.emplace_back(); }) {
#endif
res.emplace_back();
#if __cplusplus >= 201709
} else {
res.emplace();
}
#endif
}
return res;

@ -295,6 +295,11 @@ void ConversionTests::testStringConversions()
CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
splitTestActual = splitStringSimple<vector<string>>("1,2,3"s, ","s, 2);
CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
splitTestExpected = { "12", "34", "56", "" };
splitTestActual = splitString<vector<string>>("12,34,56,"s, ","s);
CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
splitTestActual = splitStringSimple<vector<string>>("12,34,56,"s, ","s);
CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
splitTestExpected = { "1", "2,3", "4,,5" };
splitTestActual = splitString<vector<string>>("1,2,,3,4,,5"s, ","s, EmptyPartsTreat::Merge, 3);
CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);

Loading…
Cancel
Save