Skip to content

Commit 35ddb77

Browse files
committed
utils.h: added helpers for efficient string concatination [skip ci]
1 parent 83664f5 commit 35ddb77

3 files changed

Lines changed: 220 additions & 3 deletions

File tree

lib/tokenize.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,8 +2418,7 @@ namespace {
24182418
while (scope && scope->parent) {
24192419
if (scope->name.empty())
24202420
break;
2421-
fullName.insert(0, " :: ");
2422-
fullName.insert(0, scope->name);
2421+
utils::string::prepend(fullName, scope->name, " :: ");
24232422
scope = scope->parent;
24242423
}
24252424
}
@@ -2588,7 +2587,7 @@ namespace {
25882587
}
25892588
// inline member function
25902589
else if ((scopeInfo->type == ScopeInfo3::Record || scopeInfo->type == ScopeInfo3::Namespace) && tok1 && Token::Match(tok1->tokAt(-1), "%name% (")) {
2591-
std::string scope = scopeInfo->name + "::" + tok1->strAt(-1);
2590+
std::string scope = utils::string::create(scopeInfo->name, "::", tok1->strAt(-1));
25922591
scopeInfo = scopeInfo->addChild(ScopeInfo3::MemberFunction, std::move(scope), tok, tok->link());
25932592
added = true;
25942593
}

lib/utils.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,73 @@ namespace utils {
437437
return result;
438438
};
439439
}
440+
441+
namespace string
442+
{
443+
template<size_t size>
444+
void concat(std::string &str, const char (&data)[size])
445+
{
446+
str.append(data, size-1);
447+
}
448+
449+
inline void concat(std::string &str, char c)
450+
{
451+
str += c;
452+
}
453+
454+
template<typename T>
455+
void concat(std::string &str, T&& t)
456+
{
457+
str.append(t);
458+
}
459+
460+
template<typename T, typename... Args>
461+
void concat(std::string& str, T&& t, Args&&... args)
462+
{
463+
concat(str, t);
464+
concat(str, args...);
465+
}
466+
467+
template<typename... Args>
468+
std::string create(char c, const Args&... args)
469+
{
470+
std::string str(1, c);
471+
concat(str, args...);
472+
return str;
473+
}
474+
475+
template<typename T, typename... Args>
476+
std::string create(const T& t, const Args&... args)
477+
{
478+
std::string str(t);
479+
concat(str, args...);
480+
return str;
481+
}
482+
483+
template<size_t size>
484+
void prepend(std::string &str, const char (&data)[size])
485+
{
486+
str.insert(0, data, size-1);
487+
}
488+
489+
inline void prepend(std::string &str, char c)
490+
{
491+
str.insert(0, 1, c);
492+
}
493+
494+
template<typename T>
495+
void prepend(std::string &str, T&& t)
496+
{
497+
str.insert(0, t);
498+
}
499+
500+
template<typename T, typename... Args>
501+
void prepend(std::string& str, T&& t, Args&&... args)
502+
{
503+
prepend(str, args...);
504+
prepend(str, t);
505+
}
506+
}
440507
}
441508

442509
#endif

test/testutils.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class TestUtils : public TestFixture {
4545
TEST_CASE(as_const);
4646
TEST_CASE(memoize);
4747
TEST_CASE(endsWith);
48+
TEST_CASE(stringConcat);
49+
TEST_CASE(stringCreate);
50+
TEST_CASE(stringPrepend);
4851
}
4952

5053
void isValidGlobPattern() const {
@@ -575,6 +578,154 @@ class TestUtils : public TestFixture {
575578
ASSERT(!::endsWith("tes", "test"));
576579
ASSERT(!::endsWith("2test", "2"));
577580
}
581+
582+
void stringConcat() const
583+
{
584+
{
585+
std::string s = "0";
586+
utils::string::concat(s, "a");
587+
utils::string::concat(s, "b");
588+
utils::string::concat(s, "c");
589+
ASSERT_EQUALS("0abc", s);
590+
}
591+
{
592+
std::string s = "0";
593+
utils::string::concat(s, "a", "b", "c");
594+
ASSERT_EQUALS("0abc", s);
595+
}
596+
{
597+
const std::string a_str = "a";
598+
const std::string b_str = "b";
599+
const std::string c_str = "c";
600+
{
601+
std::string s = "0";
602+
utils::string::concat(s, a_str);
603+
utils::string::concat(s, b_str);
604+
utils::string::concat(s, c_str);
605+
ASSERT_EQUALS("0abc", s);
606+
}
607+
{
608+
std::string s = "0";
609+
utils::string::concat(s, a_str, b_str, c_str);
610+
ASSERT_EQUALS("0abc", s);
611+
}
612+
}
613+
{
614+
std::string s = "0";
615+
utils::string::concat(s, 'a');
616+
utils::string::concat(s, 'b');
617+
utils::string::concat(s, 'c');
618+
ASSERT_EQUALS("0abc", s);
619+
}
620+
{
621+
std::string s = "0";
622+
utils::string::concat(s, 'a', 'b', 'c');
623+
ASSERT_EQUALS("0abc", s);
624+
}
625+
{
626+
const std::string a_str = "a";
627+
{
628+
std::string s = "0";
629+
utils::string::concat(s, a_str);
630+
utils::string::concat(s, 'b');
631+
utils::string::concat(s, "c");
632+
ASSERT_EQUALS("0abc", s);
633+
}
634+
{
635+
std::string s = "0";
636+
utils::string::concat(s, a_str, 'b', "c");
637+
ASSERT_EQUALS("0abc", s);
638+
}
639+
}
640+
}
641+
642+
void stringCreate() const
643+
{
644+
{
645+
std::string s = utils::string::create("a", "b", "c");
646+
ASSERT_EQUALS("abc", s);
647+
}
648+
{
649+
const std::string a_str = "a";
650+
const std::string b_str = "b";
651+
const std::string c_str = "c";
652+
{
653+
std::string s = utils::string::create(a_str, b_str, c_str);
654+
ASSERT_EQUALS("abc", s);
655+
}
656+
}
657+
{
658+
std::string s = utils::string::create('a', 'b', 'c');
659+
ASSERT_EQUALS("abc", s);
660+
}
661+
{
662+
const std::string a_str = "a";
663+
{
664+
std::string s = utils::string::create(a_str, 'b', "c");
665+
ASSERT_EQUALS("abc", s);
666+
}
667+
}
668+
}
669+
670+
void stringPrepend() const
671+
{
672+
{
673+
std::string s = "0";
674+
utils::string::prepend(s, "a");
675+
utils::string::prepend(s, "b");
676+
utils::string::prepend(s, "c");
677+
ASSERT_EQUALS("cba0", s);
678+
}
679+
{
680+
std::string s = "0";
681+
utils::string::prepend(s, "a", "b", "c");
682+
ASSERT_EQUALS("abc0", s);
683+
}
684+
{
685+
const std::string a_str = "a";
686+
const std::string b_str = "b";
687+
const std::string c_str = "c";
688+
{
689+
std::string s = "0";
690+
utils::string::prepend(s, a_str);
691+
utils::string::prepend(s, b_str);
692+
utils::string::prepend(s, c_str);
693+
ASSERT_EQUALS("cba0", s);
694+
}
695+
{
696+
std::string s = "0";
697+
utils::string::prepend(s, a_str, b_str, c_str);
698+
ASSERT_EQUALS("abc0", s);
699+
}
700+
}
701+
{
702+
std::string s = "0";
703+
utils::string::prepend(s, 'a');
704+
utils::string::prepend(s, 'b');
705+
utils::string::prepend(s, 'c');
706+
ASSERT_EQUALS("cba0", s);
707+
}
708+
{
709+
std::string s = "0";
710+
utils::string::prepend(s, 'a', 'b', 'c');
711+
ASSERT_EQUALS("abc0", s);
712+
}
713+
{
714+
const std::string a_str = "a";
715+
{
716+
std::string s = "0";
717+
utils::string::prepend(s, a_str);
718+
utils::string::prepend(s, 'b');
719+
utils::string::prepend(s, "c");
720+
ASSERT_EQUALS("cba0", s);
721+
}
722+
{
723+
std::string s = "0";
724+
utils::string::prepend(s, a_str, 'b', "c");
725+
ASSERT_EQUALS("abc0", s);
726+
}
727+
}
728+
}
578729
};
579730

580731
REGISTER_TEST(TestUtils)

0 commit comments

Comments
 (0)