Skip to content

Commit 84a60fd

Browse files
committed
Conceptualizing and rangifying join interface
1 parent f307098 commit 84a60fd

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

lib/inc/sys_string/impl/misc.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,9 @@ namespace sysstr
322322
}
323323

324324
template<class Storage>
325-
template<std::forward_iterator FwdIt>
326-
auto sys_string_t<Storage>::join(FwdIt first, FwdIt last) const -> sys_string_t<Storage>
325+
template<std::input_iterator It, std::sentinel_for<It> EndIt>
326+
requires(builder_appendable<std::iter_value_t<It>, Storage>)
327+
auto sys_string_t<Storage>::join(It first, EndIt last) const -> sys_string_t<Storage>
327328
{
328329
sys_string_builder_t<Storage> builder;
329330
bool has_one = false;

lib/inc/sys_string/sys_string.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ namespace sysstr
4949
template<class T, class Storage>
5050
concept sys_string_or_char = std::is_same_v<std::remove_cvref_t<T>, sys_string_t<Storage>> ||
5151
std::is_same_v<std::remove_cvref_t<T>, char32_t>;
52+
53+
template<class T, class Storage>
54+
concept builder_appendable = requires(sys_string_builder_t<Storage> builder, T t) {
55+
builder.append(t);
56+
};
5257
}
5358

5459
namespace sysstr::util
@@ -355,8 +360,14 @@ namespace sysstr
355360
auto split(OutIt dest, const StringOrChar & sep, size_t max_split = std::numeric_limits<size_t>::max()) const -> OutIt
356361
requires(std::output_iterator<OutIt, sys_string_t>);
357362

358-
template<std::forward_iterator FwdIt>
359-
auto join(FwdIt first, FwdIt last) const -> sys_string_t;
363+
template<std::input_iterator It, std::sentinel_for<It> EndIt>
364+
requires(builder_appendable<std::iter_value_t<It>, Storage>)
365+
auto join(It first, EndIt last) const -> sys_string_t;
366+
367+
template<std::ranges::input_range Range>
368+
requires(builder_appendable<std::ranges::range_value_t<Range>, Storage>)
369+
auto join(const Range & range) const -> sys_string_t
370+
{ return join(std::begin(range), std::end(range)); }
360371

361372
template<sys_string_or_char<Storage> StringOrChar>
362373
auto starts_with(const StringOrChar & prefix) const -> bool;

test/test_general.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,18 @@ TEST_CASE( "Join" ) {
453453
std::vector<sys_string> two = {S("Q"), S("R")};
454454

455455
CHECK(S("").join(empty.begin(), empty.end()) == S(""));
456+
CHECK(S("").join(empty) == S(""));
456457
CHECK(S("").join(one.begin(), one.end()) == S("Q"));
458+
CHECK(S("").join(one) == S("Q"));
457459
CHECK(S("").join(two.begin(), two.end()) == S("QR"));
460+
CHECK(S("").join(two) == S("QR"));
458461

459462
CHECK(S("A").join(empty.begin(), empty.end()) == S(""));
463+
CHECK(S("A").join(empty) == S(""));
460464
CHECK(S("A").join(one.begin(), one.end()) == S("Q"));
465+
CHECK(S("A").join(one) == S("Q"));
461466
CHECK(S("A").join(two.begin(), two.end()) == S("QAR"));
467+
CHECK(S("A").join(two) == S("QAR"));
462468
}
463469

464470
TEST_CASE( "Prefix" ) {

0 commit comments

Comments
 (0)