Skip to content

Commit c89fabf

Browse files
author
MacroFake
committed
Merge bitcoin/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/bitcoin@fa95315) Tree-SHA512: efd65b65722f46b221bd53140ff22bd8e45adc83617980233f28f695be3108a6ab01affd751d715134ffcb9762228ba8952e9467e590cff022c83e0f5404cb74
2 parents 3c1e75e + fa95315 commit c89fabf

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 (const 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
@@ -238,15 +238,15 @@ BOOST_AUTO_TEST_CASE(span_write_bytes)
238238
BOOST_AUTO_TEST_CASE(util_Join)
239239
{
240240
// Normal version
241-
BOOST_CHECK_EQUAL(Join({}, ", "), "");
242-
BOOST_CHECK_EQUAL(Join({"foo"}, ", "), "foo");
243-
BOOST_CHECK_EQUAL(Join({"foo", "bar"}, ", "), "foo, bar");
241+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
242+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
243+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
244244

245245
// Version with unary operator
246246
const auto op_upper = [](const std::string& s) { return ToUpper(s); };
247-
BOOST_CHECK_EQUAL(Join<std::string>({}, ", ", op_upper), "");
248-
BOOST_CHECK_EQUAL(Join<std::string>({"foo"}, ", ", op_upper), "FOO");
249-
BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
247+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
248+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
249+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
250250
}
251251

252252
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)