Skip to content

Commit b50fa09

Browse files
MacroFakevijaydasmp
authored andcommitted
Merge bitcoin#25879: refactor: Make Join() util work with any container type
fa95315 Use new Join() helper for ListBlockFilterTypes() (MacroFake) fa1c716 Make Join() util work with any container type (MacroFake) faf8da3 Remove Join() helper only used in tests (MacroFake) Pull request description: This allows to drop some code ACKs for top commit: naumenkogs: ACK fa95315 stickies-v: ACK [fa95315](bitcoin@fa95315) Tree-SHA512: efd65b65722f46b221bd53140ff22bd8e45adc83617980233f28f695be3108a6ab01affd751d715134ffcb9762228ba8952e9467e590cff022c83e0f5404cb74
1 parent ce0a046 commit b50fa09

File tree

3 files changed

+24
-40
lines changed

3 files changed

+24
-40
lines changed

src/blockfilter.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <mutex>
6-
#include <sstream>
76
#include <set>
87

98
#include <blockfilter.h>
@@ -13,6 +12,7 @@
1312
#include <script/script.h>
1413
#include <streams.h>
1514
#include <util/golombrice.h>
15+
#include <util/string.h>
1616

1717
/// SerType used to serialize parameters in GCS filter encoding.
1818
static constexpr int GCS_SER_TYPE = SER_NETWORK;
@@ -179,19 +179,7 @@ const std::set<BlockFilterType>& AllBlockFilterTypes()
179179

180180
const std::string& ListBlockFilterTypes()
181181
{
182-
static std::string type_list;
183-
184-
static std::once_flag flag;
185-
std::call_once(flag, []() {
186-
std::stringstream ret;
187-
bool first = true;
188-
for (auto entry : g_filter_types) {
189-
if (!first) ret << ", ";
190-
ret << entry.second;
191-
first = false;
192-
}
193-
type_list = ret.str();
194-
});
182+
static std::string type_list{Join(g_filter_types, ", ", [](const auto& entry) { return entry.second; })};
195183

196184
return type_list;
197185
}

src/test/util_tests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,15 @@ BOOST_AUTO_TEST_CASE(span_write_bytes)
248248
BOOST_AUTO_TEST_CASE(util_Join)
249249
{
250250
// Normal version
251-
BOOST_CHECK_EQUAL(Join({}, ", "), "");
252-
BOOST_CHECK_EQUAL(Join({"foo"}, ", "), "foo");
253-
BOOST_CHECK_EQUAL(Join({"foo", "bar"}, ", "), "foo, bar");
251+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
252+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
253+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
254254

255255
// Version with unary operator
256256
const auto op_upper = [](const std::string& s) { return ToUpper(s); };
257-
BOOST_CHECK_EQUAL(Join<std::string>({}, ", ", op_upper), "");
258-
BOOST_CHECK_EQUAL(Join<std::string>({"foo"}, ", ", op_upper), "FOO");
259-
BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
257+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
258+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
259+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
260260
}
261261

262262
BOOST_AUTO_TEST_CASE(util_ReplaceAll)

src/util/string.h

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,30 @@ void ReplaceAll(std::string& in_out, const std::string& search, const std::strin
5858
}
5959

6060
/**
61-
* Join a list of items
61+
* Join all container items. Typically used to concatenate strings but accepts
62+
* containers with elements of any type.
6263
*
63-
* @param list The list to join
64-
* @param separator The separator
65-
* @param unary_op Apply this operator to each item in the list
64+
* @param container The items to join
65+
* @param separator The separator
66+
* @param unary_op Apply this operator to each item
6667
*/
67-
template <typename T, typename BaseType, typename UnaryOp>
68-
auto Join(const std::vector<T>& list, const BaseType& separator, UnaryOp unary_op)
69-
-> decltype(unary_op(list.at(0)))
68+
template <typename C, typename S, typename UnaryOp>
69+
auto Join(const C& container, const S& separator, UnaryOp unary_op)
7070
{
71-
decltype(unary_op(list.at(0))) ret;
72-
for (size_t i = 0; i < list.size(); ++i) {
73-
if (i > 0) ret += separator;
74-
ret += unary_op(list.at(i));
71+
decltype(unary_op(*container.begin())) ret;
72+
bool first{true};
73+
for (const auto& item : container) {
74+
if (!first) ret += separator;
75+
ret += unary_op(item);
76+
first = false;
7577
}
7678
return ret;
7779
}
7880

79-
template <typename T, typename T2>
80-
T Join(const std::vector<T>& list, const T2& separator)
81+
template <typename C, typename S>
82+
auto Join(const C& container, const S& separator)
8183
{
82-
return Join(list, separator, [](const T& i) { return i; });
83-
}
84-
85-
// Explicit overload needed for c_str arguments, which would otherwise cause a substitution failure in the template above.
86-
inline std::string Join(const std::vector<std::string>& list, std::string_view separator)
87-
{
88-
return Join<std::string>(list, separator);
84+
return Join(container, separator, [](const auto& i) { return i; });
8985
}
9086

9187
/**

0 commit comments

Comments
 (0)