190 changes: 120 additions & 70 deletions std/algorithm/iteration.d

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions std/algorithm/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,13 @@ $(TR $(TDNW Comparison)
$(TR $(TDNW Iteration)
$(TDNW $(SUBMODULE iteration))
$(TD
$(SUBREF iteration, aggregate)
$(SUBREF iteration, cache)
$(SUBREF iteration, cacheBidirectional)
$(SUBREF iteration, chunkBy)
$(SUBREF iteration, each)
$(SUBREF iteration, filter)
$(SUBREF iteration, filterBidirectional)
$(SUBREF iteration, group)
$(SUBREF iteration, groupBy)
$(SUBREF iteration, joiner)
$(SUBREF iteration, map)
$(SUBREF iteration, reduce)
Expand Down
18 changes: 17 additions & 1 deletion std/conv.d
Original file line number Diff line number Diff line change
Expand Up @@ -1989,7 +1989,7 @@ Target parse(Target, Source)(ref Source s)
Target v = cast(Target)c;
while (!s.empty)
{
c = s.front - '0';
c = cast(typeof(c)) (s.front - '0');
if (c > 9)
break;

Expand Down Expand Up @@ -2206,6 +2206,22 @@ Lerr:
assertThrown!ConvOverflowException("-92233720368547758080".to!long());
}

// Issue 14396
@safe pure unittest
{
struct StrInputRange
{
this (string s) { str = s; }
char front() const @property { return str[front_index]; }
char popFront() { return str[front_index++]; }
bool empty() const @property { return str.length <= front_index; }
string str;
size_t front_index = 0;
}
auto input = StrInputRange("777");
assert(parse!int(input) == 777);
}

/// ditto
Target parse(Target, Source)(ref Source s, uint radix)
if (isSomeChar!(ElementType!Source) &&
Expand Down
2 changes: 1 addition & 1 deletion std/experimental/logger/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,7 @@ version (unittest)
string msg = null;
LogLevel lvl;

this(const LogLevel lv = LogLevel.info) @safe
this(const LogLevel lv = LogLevel.all) @safe
{
super(lv);
}
Expand Down
4 changes: 2 additions & 2 deletions std/experimental/logger/multilogger.d
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ class MultiLogger : Logger
Params:
lv = The $(D LogLevel) for the $(D MultiLogger). By default the
$(D LogLevel) for $(D MultiLogger) is $(D LogLevel.info).
$(D LogLevel) for $(D MultiLogger) is $(D LogLevel.all).
Example:
-------------
auto l1 = new MultiLogger(LogLevel.trace);
-------------
*/
this(const LogLevel lv = LogLevel.info) @safe
this(const LogLevel lv = LogLevel.all) @safe
{
super(lv);
}
Expand Down
4 changes: 2 additions & 2 deletions std/experimental/logger/nulllogger.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class NullLogger : Logger
Params:
lv = The $(D LogLevel) for the $(D NullLogger). By default the $(D LogLevel)
for $(D NullLogger) is $(D LogLevel.info).
for $(D NullLogger) is $(D LogLevel.all).
*/
this(const LogLevel lv = LogLevel.info) @safe
this(const LogLevel lv = LogLevel.all) @safe
{
super(lv);
this.fatalHandler = delegate() {};
Expand Down
19 changes: 19 additions & 0 deletions std/range/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -7142,6 +7142,17 @@ sgi.com/tech/stl/binary_search.html, binary_search).
}
return false;
}

// groupBy
/**
Returns a range of subranges of elements that are equivalent according to the
sorting relation.
*/
auto groupBy()()
{
import std.algorithm.iteration : chunkBy;
return _input.chunkBy!((a, b) => !predFun(a, b) && !predFun(b, a));
}
}

///
Expand Down Expand Up @@ -7271,6 +7282,14 @@ that break its sortedness, $(D SortedRange) will work erratically.
auto s = assumeSorted(arr);
}

unittest
{
import std.algorithm.comparison : equal;
int[] arr = [100, 101, 102, 200, 201, 300];
auto s = assumeSorted!((a, b) => a / 100 < b / 100)(arr);
assert(s.groupBy.equal!equal([[100, 101, 102], [200, 201], [300]]));
}

// Test on an input range
unittest
{
Expand Down