Skip to content

Commit 178802d

Browse files
authored
Merge pull request #3997 from NlightNFotis/string_join_enhancement
Add overload of join_string() that takes a function argument
2 parents 0e6538a + f98cbed commit 178802d

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

src/util/string_utils.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,51 @@ std::string trim_from_last_delimiter(
4747
/// \param b: Iterator pointing to first item to print
4848
/// \param e: Iterator pointing past last item to print
4949
/// \param delimiter: Object to print between each item in the iterator range
50+
/// \param transform_func: Transform to apply to the value returned by the
51+
/// iterator
5052
/// \return A reference to the ostream that was passed in
51-
template<typename Stream, typename It, typename Delimiter>
53+
template <
54+
typename Stream,
55+
typename It,
56+
typename Delimiter,
57+
typename TransformFunc>
5258
Stream &join_strings(
53-
Stream &os,
59+
Stream &&os,
5460
const It b,
5561
const It e,
56-
const Delimiter &delimiter)
62+
const Delimiter &delimiter,
63+
TransformFunc &&transform_func)
5764
{
5865
if(b==e)
5966
{
6067
return os;
6168
}
62-
os << *b;
69+
os << transform_func(*b);
6370
for(auto it=std::next(b); it!=e; ++it)
6471
{
65-
os << delimiter << *it;
72+
os << delimiter << transform_func(*it);
6673
}
6774
return os;
6875
}
6976

77+
/// Prints items to an stream, separated by a constant delimiter
78+
/// \tparam It: An iterator type
79+
/// \tparam Delimiter: A delimiter type which supports printing to ostreams
80+
/// \param os: An ostream to write to
81+
/// \param b: Iterator pointing to first item to print
82+
/// \param e: Iterator pointing past last item to print
83+
/// \param delimiter: Object to print between each item in the iterator range
84+
/// \return A reference to the ostream that was passed in
85+
template <typename Stream, typename It, typename Delimiter>
86+
Stream &
87+
join_strings(Stream &&os, const It b, const It e, const Delimiter &delimiter)
88+
{
89+
using value_type = decltype(*b);
90+
// Call auxiliary function with identity function
91+
return join_strings(
92+
os, b, e, delimiter, [](const value_type &x) { return x; });
93+
}
94+
7095
/// Generic escaping of strings; this is not meant to be a particular
7196
/// programming language.
7297
std::string escape(const std::string &);

unit/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ SRC += analyses/ai/ai.cpp \
6969
util/simplify_expr.cpp \
7070
util/small_map.cpp \
7171
util/small_shared_two_way_ptr.cpp \
72-
util/std_expr.cpp \
72+
util/std_expr.cpp \
73+
util/string_utils/join_string.cpp \
7374
util/string_utils/split_string.cpp \
7475
util/string_utils/strip_string.cpp \
7576
util/symbol_table.cpp \
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests of join_string
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// join_string Unit Tests
11+
12+
#include <sstream>
13+
#include <string>
14+
#include <vector>
15+
16+
#include <testing-utils/use_catch.h>
17+
#include <util/string_utils.h>
18+
19+
TEST_CASE(
20+
"join_strings() should apply the function argument its passed to the "
21+
"elements of the container",
22+
"[core][utils][string_utils][join_strings]")
23+
{
24+
std::vector<int> vec{1, 2, 3};
25+
auto result = join_strings(
26+
std::ostringstream(),
27+
vec.begin(),
28+
vec.end(),
29+
"-",
30+
[](int x) { return std::to_string(x + 1); })
31+
.str();
32+
REQUIRE(result == "2-3-4");
33+
}
34+
35+
TEST_CASE(
36+
"join_strings() when passed no function argument should apply the default "
37+
"identity function to the elements of the container",
38+
"[core][utils][string_utils][join_strings]")
39+
{
40+
std::vector<int> vec{1, 2, 3};
41+
auto result =
42+
join_strings(std::ostringstream(), vec.begin(), vec.end(), ",").str();
43+
REQUIRE(result == "1,2,3");
44+
}

0 commit comments

Comments
 (0)