Add fresh concatStringsSep without bug

The buggy version was previously renamed to
dropEmptyInitThenConcatStringsSep
This commit is contained in:
Robert Hensing 2024-07-12 23:02:08 +02:00
parent 79eb0adf9d
commit a681d354e7
5 changed files with 150 additions and 0 deletions

View file

@ -148,6 +148,7 @@ sources = files(
'signature/signer.cc', 'signature/signer.cc',
'source-accessor.cc', 'source-accessor.cc',
'source-path.cc', 'source-path.cc',
'strings.cc',
'suggestions.cc', 'suggestions.cc',
'tarfile.cc', 'tarfile.cc',
'terminal.cc', 'terminal.cc',
@ -215,6 +216,8 @@ headers = [config_h] + files(
'source-accessor.hh', 'source-accessor.hh',
'source-path.hh', 'source-path.hh',
'split.hh', 'split.hh',
'strings.hh',
'strings-inline.hh',
'suggestions.hh', 'suggestions.hh',
'sync.hh', 'sync.hh',
'tarfile.hh', 'tarfile.hh',

View file

@ -0,0 +1,31 @@
#pragma once
#include "strings.hh"
namespace nix {
template<class C>
std::string concatStringsSep(const std::string_view sep, const C & ss)
{
size_t size = 0;
bool tail = false;
// need a cast to string_view since this is also called with Symbols
for (const auto & s : ss) {
if (tail)
size += sep.size();
size += std::string_view(s).size();
tail = true;
}
std::string s;
s.reserve(size);
tail = false;
for (auto & i : ss) {
if (tail)
s += sep;
s += i;
tail = true;
}
return s;
}
} // namespace nix

12
src/libutil/strings.cc Normal file
View file

@ -0,0 +1,12 @@
#include <string>
#include "strings-inline.hh"
#include "util.hh"
namespace nix {
template std::string concatStringsSep(std::string_view, const Strings &);
template std::string concatStringsSep(std::string_view, const StringSet &);
template std::string concatStringsSep(std::string_view, const std::vector<std::string> &);
} // namespace nix

21
src/libutil/strings.hh Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include <list>
#include <set>
#include <string_view>
#include <string>
#include <vector>
namespace nix {
/**
* Concatenate the given strings with a separator between the elements.
*/
template<class C>
std::string concatStringsSep(const std::string_view sep, const C & ss);
extern template std::string concatStringsSep(std::string_view, const std::list<std::string> &);
extern template std::string concatStringsSep(std::string_view, const std::set<std::string> &);
extern template std::string concatStringsSep(std::string_view, const std::vector<std::string> &);
}

View file

@ -0,0 +1,83 @@
#include <gtest/gtest.h>
#include "strings.hh"
namespace nix {
using Strings = std::vector<std::string>;
/* ----------------------------------------------------------------------------
* concatStringsSep
* --------------------------------------------------------------------------*/
TEST(concatStringsSep, empty)
{
Strings strings;
ASSERT_EQ(concatStringsSep(",", strings), "");
}
TEST(concatStringsSep, justOne)
{
Strings strings;
strings.push_back("this");
ASSERT_EQ(concatStringsSep(",", strings), "this");
}
TEST(concatStringsSep, emptyString)
{
Strings strings;
strings.push_back("");
ASSERT_EQ(concatStringsSep(",", strings), "");
}
TEST(concatStringsSep, emptyStrings)
{
Strings strings;
strings.push_back("");
strings.push_back("");
ASSERT_EQ(concatStringsSep(",", strings), ",");
}
TEST(concatStringsSep, threeEmptyStrings)
{
Strings strings;
strings.push_back("");
strings.push_back("");
strings.push_back("");
ASSERT_EQ(concatStringsSep(",", strings), ",,");
}
TEST(concatStringsSep, buildCommaSeparatedString)
{
Strings strings;
strings.push_back("this");
strings.push_back("is");
strings.push_back("great");
ASSERT_EQ(concatStringsSep(",", strings), "this,is,great");
}
TEST(concatStringsSep, buildStringWithEmptySeparator)
{
Strings strings;
strings.push_back("this");
strings.push_back("is");
strings.push_back("great");
ASSERT_EQ(concatStringsSep("", strings), "thisisgreat");
}
TEST(concatStringsSep, buildSingleString)
{
Strings strings;
strings.push_back("this");
ASSERT_EQ(concatStringsSep(",", strings), "this");
}
} // namespace nix