# line 163 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range, std.stdio; import std.typecons : tuple; ulong counter = 0; double fun(int x) { ++counter; // http://en.wikipedia.org/wiki/Quartic_function return ( (x + 4.0) * (x + 1.0) * (x - 1.0) * (x - 3.0) ) / 14.0 + 0.5; } // Without cache, with array (greedy) auto result1 = iota(-4, 5).map!(a =>tuple(a, fun(a)))() .filter!(a => a[1] < 0)() .map!(a => a[0])() .array(); // the values of x that have a negative y are: assert(equal(result1, [-3, -2, 2])); // Check how many times fun was evaluated. // As many times as the number of items in both source and result. assert(counter == iota(-4, 5).length + result1.length); counter = 0; // Without array, with cache (lazy) auto result2 = iota(-4, 5).map!(a =>tuple(a, fun(a)))() .cache() .filter!(a => a[1] < 0)() .map!(a => a[0])(); // the values of x that have a negative y are: assert(equal(result2, [-3, -2, 2])); // Check how many times fun was evaluated. // Only as many times as the number of items in source. assert(counter == iota(-4, 5).length); } # line 218 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range; int i = 0; auto r = iota(0, 4).tee!((a){i = a;}, No.pipeOnPop); auto r1 = r.take(3).cache(); auto r2 = r.cache().take(3); assert(equal(r1, [0, 1, 2])); assert(i == 2); //The last "seen" element was 2. The data in cache has been cleared. assert(equal(r2, [0, 1, 2])); assert(i == 3); //cache has accessed 3. It is still stored internally by cache. } # line 495 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range : chain; int[] arr1 = [ 1, 2, 3, 4 ]; int[] arr2 = [ 5, 6 ]; auto squares = map!(a => a * a)(chain(arr1, arr2)); assert(equal(squares, [ 1, 4, 9, 16, 25, 36 ])); } # line 510 @safe unittest { import std.algorithm.iteration; auto sums = [2, 4, 6, 8]; auto products = [1, 4, 9, 16]; size_t i = 0; foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a")) { assert(result[0] == sums[i]); assert(result[1] == products[i]); ++i; } } # line 528 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.conv : to; alias stringize = map!(to!string); assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ])); } # line 955 @system unittest { import std.algorithm.iteration; import std.range : iota; long[] arr; iota(5).each!(n => arr ~= n); assert(arr == [0, 1, 2, 3, 4]); // If the range supports it, the value can be mutated in place arr.each!((ref n) => n++); assert(arr == [1, 2, 3, 4, 5]); arr.each!"a++"; assert(arr == [2, 3, 4, 5, 6]); // by-ref lambdas are not allowed for non-ref ranges static assert(!is(typeof(arr.map!(n => n).each!((ref n) => n++)))); // The default predicate consumes the range auto m = arr.map!(n => n); (&m).each(); assert(m.empty); // Indexes are also available for in-place mutations arr[] = 0; arr.each!"a=i"(); assert(arr == [0, 1, 2, 3, 4]); // opApply iterators work as well static class S { int x; int opApply(scope int delegate(ref int _x) dg) { return dg(x); } } auto s = new S; s.each!"a++"; assert(s.x == 1); } # line 1100 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.math : approxEqual; import std.range; int[] arr = [ 1, 2, 3, 4, 5 ]; // Sum all elements auto small = filter!(a => a < 3)(arr); assert(equal(small, [ 1, 2 ])); // Sum again, but with Uniform Function Call Syntax (UFCS) auto sum = arr.filter!(a => a < 3); assert(equal(sum, [ 1, 2 ])); // In combination with chain() to span multiple ranges int[] a = [ 3, -2, 400 ]; int[] b = [ 100, -101, 102 ]; auto r = chain(a, b).filter!(a => a > 0); assert(equal(r, [ 3, 400, 100, 102 ])); // Mixing convertible types is fair game, too double[] c = [ 2.5, 3.0 ]; auto r1 = chain(c, a, b).filter!(a => cast(int) a != a); assert(approxEqual(r1, [ 2.5 ])); } # line 1320 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range; int[] arr = [ 1, 2, 3, 4, 5 ]; auto small = filterBidirectional!("a < 3")(arr); static assert(isBidirectionalRange!(typeof(small))); assert(small.back == 2); assert(equal(small, [ 1, 2 ])); assert(equal(retro(small), [ 2, 1 ])); // In combination with chain() to span multiple ranges int[] a = [ 3, -2, 400 ]; int[] b = [ 100, -101, 102 ]; auto r = filterBidirectional!("a > 0")(chain(a, b)); assert(r.back == 102); } # line 1502 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.typecons : tuple, Tuple; int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ]; assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ][])); } # line 1516 @safe unittest { import std.algorithm.iteration; import std.algorithm.sorting : sort; import std.array : assocArray; uint[string] result; auto range = ["a", "b", "a", "c", "b", "c", "c", "d", "e"]; result = range.sort!((a, b) => a < b) .group .assocArray; assert(result == ["a": 2U, "b": 2U, "c": 3U, "d": 1U, "e": 1U]); } # line 1907 @system unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; // Grouping by particular attribute of each element: auto data = [ [1, 1], [1, 2], [2, 2], [2, 3] ]; auto r1 = data.chunkBy!((a,b) => a[0] == b[0]); assert(r1.equal!equal([ [[1, 1], [1, 2]], [[2, 2], [2, 3]] ])); auto r2 = data.chunkBy!((a,b) => a[1] == b[1]); assert(r2.equal!equal([ [[1, 1]], [[1, 2], [2, 2]], [[2, 3]] ])); } # line 1957 @system unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range.primitives; import std.typecons : tuple; // Grouping by particular attribute of each element: auto range = [ [1, 1], [1, 1], [1, 2], [2, 2], [2, 3], [2, 3], [3, 3] ]; auto byX = chunkBy!(a => a[0])(range); auto expected1 = [ tuple(1, [[1, 1], [1, 1], [1, 2]]), tuple(2, [[2, 2], [2, 3], [2, 3]]), tuple(3, [[3, 3]]) ]; foreach (e; byX) { assert(!expected1.empty); assert(e[0] == expected1.front[0]); assert(e[1].equal(expected1.front[1])); expected1.popFront(); } auto byY = chunkBy!(a => a[1])(range); auto expected2 = [ tuple(1, [[1, 1], [1, 1]]), tuple(2, [[1, 2], [2, 2]]), tuple(3, [[2, 3], [2, 3], [3, 3]]) ]; foreach (e; byY) { assert(!expected2.empty); assert(e[0] == expected2.front[0]); assert(e[1].equal(expected2.front[1])); expected2.popFront(); } } # line 2280 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.conv : text; assert(["abc", "def"].joiner.equal("abcdef")); assert(["Mary", "has", "a", "little", "lamb"] .joiner("...") .equal("Mary...has...a...little...lamb")); assert(["", "abc"].joiner("xyz").equal("xyzabc")); assert([""].joiner("xyz").equal("")); assert(["", ""].joiner("xyz").equal("xyz")); } # line 2883 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : max, min; import std.math : approxEqual; import std.range; int[] arr = [ 1, 2, 3, 4, 5 ]; // Sum all elements auto sum = reduce!((a,b) => a + b)(0, arr); assert(sum == 15); // Sum again, using a string predicate with "a" and "b" sum = reduce!"a + b"(0, arr); assert(sum == 15); // Compute the maximum of all elements auto largest = reduce!(max)(arr); assert(largest == 5); // Max again, but with Uniform Function Call Syntax (UFCS) largest = arr.reduce!(max); assert(largest == 5); // Compute the number of odd elements auto odds = reduce!((a,b) => a + (b & 1))(0, arr); assert(odds == 3); // Compute the sum of squares auto ssquares = reduce!((a,b) => a + b * b)(0, arr); assert(ssquares == 55); // Chain multiple ranges into seed int[] a = [ 3, 4 ]; int[] b = [ 100 ]; auto r = reduce!("a + b")(chain(a, b)); assert(r == 107); // Mixing convertible types is fair game, too double[] c = [ 2.5, 3.0 ]; auto r1 = reduce!("a + b")(chain(a, b, c)); assert(approxEqual(r1, 112.5)); // To minimize nesting of parentheses, Uniform Function Call Syntax can be used auto r2 = chain(a, b, c).reduce!("a + b"); assert(approxEqual(r2, 112.5)); } # line 2938 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : max, min; import std.math : approxEqual, sqrt; import std.typecons : tuple, Tuple; double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ]; // Compute minimum and maximum in one pass auto r = reduce!(min, max)(a); // The type of r is Tuple!(int, int) assert(approxEqual(r[0], 2)); // minimum assert(approxEqual(r[1], 11)); // maximum // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); assert(approxEqual(r[0], 35)); // sum assert(approxEqual(r[1], 233)); // sum of squares // Compute average and standard deviation from the above auto avg = r[0] / a.length; auto stdev = sqrt(r[1] / a.length - avg * avg); } # line 3210 @safe pure unittest { import std.algorithm.iteration; immutable arr = [1, 2, 3, 4, 5]; // Sum all elements assert(arr.fold!((a, b) => a + b) == 15); // Sum all elements with explicit seed assert(arr.fold!((a, b) => a + b)(6) == 21); import std.algorithm.comparison : min, max; import std.typecons : tuple; // Compute minimum and maximum at the same time assert(arr.fold!(min, max) == tuple(1, 5)); // Compute minimum and maximum at the same time with seeds assert(arr.fold!(min, max)(0, 7) == tuple(0, 7)); // Can be used in a UFCS chain assert(arr.map!(a => a + 1).fold!((a, b) => a + b) == 20); // Return the last element of any range assert(arr.fold!((a, b) => b) == 5); } # line 3418 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : max, min; import std.array : array; import std.math : approxEqual; import std.range : chain; int[] arr = [1, 2, 3, 4, 5]; // Partial sum of all elements auto sum = cumulativeFold!((a, b) => a + b)(arr, 0); assert(sum.array == [1, 3, 6, 10, 15]); // Partial sum again, using a string predicate with "a" and "b" auto sum2 = cumulativeFold!"a + b"(arr, 0); assert(sum2.array == [1, 3, 6, 10, 15]); // Compute the partial maximum of all elements auto largest = cumulativeFold!max(arr); assert(largest.array == [1, 2, 3, 4, 5]); // Partial max again, but with Uniform Function Call Syntax (UFCS) largest = arr.cumulativeFold!max; assert(largest.array == [1, 2, 3, 4, 5]); // Partial count of odd elements auto odds = arr.cumulativeFold!((a, b) => a + (b & 1))(0); assert(odds.array == [1, 1, 2, 2, 3]); // Compute the partial sum of squares auto ssquares = arr.cumulativeFold!((a, b) => a + b * b)(0); assert(ssquares.array == [1, 5, 14, 30, 55]); // Chain multiple ranges into seed int[] a = [3, 4]; int[] b = [100]; auto r = cumulativeFold!"a + b"(chain(a, b)); assert(r.array == [3, 7, 107]); // Mixing convertible types is fair game, too double[] c = [2.5, 3.0]; auto r1 = cumulativeFold!"a + b"(chain(a, b, c)); assert(approxEqual(r1, [3, 7, 107, 109.5, 112.5])); // To minimize nesting of parentheses, Uniform Function Call Syntax can be used auto r2 = chain(a, b, c).cumulativeFold!"a + b"; assert(approxEqual(r2, [3, 7, 107, 109.5, 112.5])); } # line 3474 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : max, min; import std.algorithm.iteration : map; import std.math : approxEqual; import std.typecons : tuple; double[] a = [3.0, 4, 7, 11, 3, 2, 5]; // Compute minimum and maximum in one pass auto r = a.cumulativeFold!(min, max); // The type of r is Tuple!(int, int) assert(approxEqual(r.map!"a[0]", [3, 3, 3, 3, 3, 2, 2])); // minimum assert(approxEqual(r.map!"a[1]", [3, 4, 7, 11, 11, 11, 11])); // maximum // Compute sum and sum of squares in one pass auto r2 = a.cumulativeFold!("a + b", "a + b * b")(tuple(0.0, 0.0)); assert(approxEqual(r2.map!"a[0]", [3, 7, 14, 25, 28, 30, 35])); // sum assert(approxEqual(r2.map!"a[1]", [9, 25, 74, 195, 204, 208, 233])); // sum of squares } # line 3831 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ]; int[][] w = [ [1, 2], [], [3], [4, 5], [] ]; assert(equal(splitter(a, 0), w)); a = [ 0 ]; assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ])); a = [ 0, 1 ]; assert(equal(splitter(a, 0), [ [], [1] ])); w = [ [0], [1], [2] ]; assert(equal(splitter!"a.front == b"(w, 1), [ [[0]], [[2]] ])); } # line 4069 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; assert(equal(splitter("hello world", " "), [ "hello", "world" ])); int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ]; int[][] w = [ [1, 2], [3, 0, 4, 5, 0] ]; assert(equal(splitter(a, [0, 0]), w)); a = [ 0, 0 ]; assert(equal(splitter(a, [0, 0]), [ (int[]).init, (int[]).init ])); a = [ 0, 0, 1 ]; assert(equal(splitter(a, [0, 0]), [ [], [1] ])); } # line 4218 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range.primitives : front; assert(equal(splitter!(a => a == ' ')("hello world"), [ "hello", "", "world" ])); int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ]; int[][] w = [ [1, 2], [], [3], [4, 5], [] ]; assert(equal(splitter!(a => a == 0)(a), w)); a = [ 0 ]; assert(equal(splitter!(a => a == 0)(a), [ (int[]).init, (int[]).init ])); a = [ 0, 1 ]; assert(equal(splitter!(a => a == 0)(a), [ [], [1] ])); w = [ [0], [1], [2] ]; assert(equal(splitter!(a => a.front == 1)(w), [ [[0]], [[2]] ])); } # line 4507 @safe pure unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; auto a = " a bcd ef gh "; assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][])); } # line 4820 @safe pure nothrow unittest { import std.algorithm.iteration; import std.range; //simple integral sumation assert(sum([ 1, 2, 3, 4]) == 10); //with integral promotion assert(sum([false, true, true, false, true]) == 3); assert(sum(ubyte.max.repeat(100)) == 25500); //The result may overflow assert(uint.max.repeat(3).sum() == 4294967293U ); //But a seed can be used to change the sumation primitive assert(uint.max.repeat(3).sum(ulong.init) == 12884901885UL); //Floating point sumation assert(sum([1.0, 2.0, 3.0, 4.0]) == 10); //Floating point operations have double precision minimum static assert(is(typeof(sum([1F, 2F, 3F, 4F])) == double)); assert(sum([1F, 2, 3, 4]) == 10); //Force pair-wise floating point sumation on large integers import std.math : approxEqual; assert(iota(ulong.max / 2, ulong.max / 2 + 4096).sum(0.0) .approxEqual((ulong.max / 2) * 4096.0 + 4096^^2 / 2)); } # line 4952 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.algorithm.mutation : copy; int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ]; assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][])); // Filter duplicates in-place using copy arr.length -= arr.uniq().copy(arr).length; assert(arr == [ 1, 2, 3, 4, 5 ]); // Note that uniqueness is only determined consecutively; duplicated // elements separated by an intervening different element will not be // eliminated: assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1])); } # line 5178 @safe unittest { import std.algorithm.iteration; import std.algorithm.comparison : equal; import std.range : iota; assert(equal!equal(iota(3).permutations, [[0, 1, 2], [1, 0, 2], [2, 0, 1], [0, 2, 1], [1, 2, 0], [2, 1, 0]])); }