Refactor: reduce global imports.

This commit is contained in:
H. S. Teoh 2015-01-17 19:04:44 -08:00
parent 9dc4c34379
commit 5551facc2f
5 changed files with 206 additions and 24 deletions

View file

@ -1,18 +1,12 @@
// Written in the D programming language.
module std.algorithm.comparison;
import std.algorithm : reverse; // FIXME: ugly hack
import std.algorithm.iteration : filter, map;
// FIXME
import std.functional; // : unaryFun, binaryFun;
import std.range.primitives;
import std.traits;
// FIXME
import std.typecons; // : tuple, Tuple;
// FIXME
import std.typetuple; // : TypeTuple, staticMap, allSatisfy, anySatisfy;
/**
Find $(D value) _among $(D values), returning the 1-based index
@ -80,6 +74,8 @@ efficient search, but one that only supports matching on equality:
@safe unittest
{
import std.typetuple : TypeTuple;
if (auto pos = 3.among(1, 2, 3))
assert(pos == 3);
else
@ -307,6 +303,7 @@ auto castSwitch(choices...)(Object switchObject)
///
unittest
{
import std.algorithm.iteration : map;
import std.format : format;
class A
@ -714,6 +711,7 @@ range of range (of range...) comparisons.
@safe unittest
{
import std.algorithm.iteration : map;
import std.math : approxEqual;
import std.internal.test.dummyrange;
@ -879,6 +877,8 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
EditOp[] path()
{
import std.algorithm : reverse; // FIXME
EditOp[] result;
size_t i = rows - 1, j = cols - 1;
// restore the path
@ -1052,6 +1052,7 @@ size_t levenshteinDistance(alias equals = "a == b", Range1, Range2)
///
@safe unittest
{
import std.algorithm.iteration : filter;
import std.uni : toUpper;
assert(levenshteinDistance("cat", "rat") == 1);

View file

@ -1,17 +1,10 @@
// Written in the D programming language.
module std.algorithm.iteration;
// FIXME
import std.algorithm : algoFormat, copy, find;
import std.algorithm.comparison : equal, max, min;
// FIXME
import std.functional; // : unaryFun, binaryFun;
import std.range.primitives;
import std.traits;
// FIXME
import std.typetuple; // : TypeTuple, staticMap, allSatisfy, anySatisfy;
/++
$(D cache) eagerly evaluates $(D front) of $(D range)
@ -54,6 +47,7 @@ if (isBidirectionalRange!Range)
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.stdio, std.range;
import std.typecons : tuple;
@ -108,6 +102,7 @@ same cost or side effects.
+/
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range;
int i = 0;
@ -124,6 +119,7 @@ same cost or side effects.
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range;
auto a = [1, 2, 3, 4];
assert(equal(a.map!"(a - 1)*a"().cache(), [ 0, 2, 6, 12]));
@ -136,6 +132,8 @@ same cost or side effects.
@safe unittest
{
import std.algorithm.comparison : equal;
//immutable test
static struct S
{
@ -152,6 +150,8 @@ same cost or side effects.
@safe pure nothrow unittest
{
import std.algorithm.comparison : equal;
//safety etc
auto a = [1, 2, 3, 4];
assert(equal(a.cache(), a));
@ -192,6 +192,8 @@ private struct Cache(R, bool bidir)
private
{
import std.typetuple : TypeTuple;
alias E = ElementType!R;
alias UE = Unqual!E;
@ -326,6 +328,8 @@ template map(fun...) if (fun.length >= 1)
{
auto map(Range)(Range r) if (isInputRange!(Unqual!Range))
{
import std.typetuple : staticMap;
alias AppliedReturnType(alias f) = typeof(f(r.front));
static if (fun.length > 1)
@ -355,6 +359,7 @@ template map(fun...) if (fun.length >= 1)
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range : chain;
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
@ -387,6 +392,7 @@ it separately:
*/
@safe unittest
{
import std.algorithm.comparison : equal;
import std.conv : to;
alias stringize = map!(to!string);
@ -504,6 +510,7 @@ private struct MapResult(alias fun, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.conv : to;
import std.functional : adjoin;
@ -525,6 +532,7 @@ private struct MapResult(alias fun, Range)
unittest
{
import std.algorithm.comparison : equal;
import std.internal.test.dummyrange;
import std.ascii : toUpper;
import std.range;
@ -626,6 +634,7 @@ unittest
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range;
auto LL = iota(1L, 4L);
auto m = map!"a*a"(LL);
@ -650,6 +659,7 @@ unittest
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range;
//slicing infinites
auto rr = iota(0, 5).cycle().map!"a * a"();
@ -693,6 +703,7 @@ template filter(alias predicate) if (is(typeof(unaryFun!predicate)))
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.math : approxEqual;
import std.range;
@ -767,6 +778,7 @@ private struct FilterResult(alias pred, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.internal.test.dummyrange;
import std.range;
@ -822,6 +834,8 @@ private struct FilterResult(alias pred, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
int[] a = [ 3, 4 ];
const aConst = a;
auto r = filter!("a > 3")(aConst);
@ -840,6 +854,7 @@ private struct FilterResult(alias pred, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.functional : compose, pipe;
assert(equal(compose!(map!"2 * a", filter!"a & 1")([1,2,3,4,5]),
@ -850,6 +865,8 @@ private struct FilterResult(alias pred, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
int x = 10;
int underX(int a) { return a < x; }
const(int)[] list = [ 1, 2, 10, 11, 3, 4 ];
@ -881,7 +898,9 @@ template filterBidirectional(alias pred)
///
@safe unittest
{
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)));
@ -1045,6 +1064,7 @@ Group!(pred, Range) group(alias pred = "a == b", Range)(Range r)
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.typecons : tuple, Tuple;
int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
@ -1054,6 +1074,7 @@ Group!(pred, Range) group(alias pred = "a == b", Range)(Range r)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.internal.test.dummyrange;
import std.typecons : tuple, Tuple;
@ -1359,6 +1380,8 @@ auto groupBy(alias pred, EquivRelation equivRelation, Range)(Range r)
/// Showing usage with binary predicate:
@safe unittest
{
import std.algorithm.comparison : equal;
// Grouping by particular attribute of each element:
auto data = [
[1, 1],
@ -1393,6 +1416,8 @@ auto groupBy(alias pred, EquivRelation equivRelation, Range)(Range r)
/// Showing usage with unary predicate:
pure @safe nothrow unittest
{
import std.algorithm.comparison : equal;
// Grouping by particular attribute of each element:
auto range =
[
@ -1436,6 +1461,8 @@ pure @safe nothrow unittest
pure @safe nothrow unittest
{
import std.algorithm.comparison : equal;
struct Item { int x, y; }
// Force R to have only an input range API with reference semantics, so
@ -1504,6 +1531,7 @@ pure @safe nothrow unittest
// Issue 13595
unittest
{
import std.algorithm.comparison : equal;
auto r = [1, 2, 3, 4, 5, 6, 7, 8, 9].groupBy!((x, y) => ((x*y) % 3) == 0);
assert(r.equal!equal([
[1],
@ -1698,6 +1726,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.conv : text;
debug(std_algorithm) scope(success)
@ -1717,6 +1746,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
unittest
{
import std.algorithm.comparison : equal;
import std.range.primitives;
import std.range.interfaces;
// joiner() should work for non-forward ranges too.
@ -1726,6 +1756,7 @@ unittest
unittest
{
import std.algorithm.comparison : equal;
import std.range;
// Related to issue 8061
@ -1774,6 +1805,8 @@ unittest
@safe unittest
{
import std.algorithm.comparison : equal;
// Transience correctness test
struct TransientRange
{
@ -1909,6 +1942,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
unittest
{
import std.algorithm.comparison : equal;
import std.range.interfaces;
import std.range : repeat;
@ -1951,6 +1985,8 @@ unittest
@safe unittest
{
import std.algorithm.comparison : equal;
struct TransientRange
{
@safe:
@ -1993,6 +2029,9 @@ unittest
@safe unittest
{
import std.algorithm : algoFormat; // FIXME
import std.algorithm.comparison : equal;
struct TransientRange
{
@safe:
@ -2069,6 +2108,8 @@ See_Also:
+/
template reduce(fun...) if (fun.length >= 1)
{
import std.typetuple : staticMap;
alias binfuns = staticMap!(binaryFun, fun);
static if (fun.length > 1)
import std.typecons : tuple, isTuple;
@ -2195,6 +2236,7 @@ remarkable power and flexibility.
*/
@safe unittest
{
import std.algorithm.comparison : max, min;
import std.math : approxEqual;
import std.range;
@ -2249,6 +2291,7 @@ The number of seeds must be correspondingly increased.
*/
@safe unittest
{
import std.algorithm.comparison : max, min;
import std.math : approxEqual, sqrt;
import std.typecons : tuple, Tuple;
@ -2270,6 +2313,7 @@ The number of seeds must be correspondingly increased.
unittest
{
import std.algorithm.comparison : max, min;
import std.exception : assertThrown;
import std.range;
import std.typecons : tuple, Tuple;
@ -2343,6 +2387,7 @@ unittest
@safe unittest
{
// Issue #10408 - Two-function reduce of a const array.
import std.algorithm.comparison : max, min;
import std.typecons : tuple, Tuple;
const numbers = [10, 30, 20];
@ -2387,6 +2432,7 @@ unittest
int fun(int a, int b){return a + b + 1;}
auto foo()
{
import std.algorithm.comparison : max;
import std.typecons : tuple, Tuple;
auto a = reduce!(fun)([1, 2, 3]);
@ -2404,6 +2450,7 @@ unittest
@safe unittest
{
import std.algorithm.comparison : max, min;
import std.typecons : tuple, Tuple;
//http://forum.dlang.org/thread/oghtttkopzjshsuflelk@forum.dlang.org
@ -2419,6 +2466,7 @@ unittest
@safe unittest //12569
{
import std.algorithm.comparison : max, min;
import std.typecons: tuple;
dchar c = 'a';
reduce!(min, max)(tuple(c, c), "hello"); // OK
@ -2486,6 +2534,7 @@ auto splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s)
if (is(typeof(binaryFun!pred(r.front, s)) : bool)
&& ((hasSlicing!Range && hasLength!Range) || isNarrowString!Range))
{
import std.algorithm : find; // FIXME
import std.conv : unsigned;
static struct Result
@ -2640,6 +2689,8 @@ if (is(typeof(binaryFun!pred(r.front, s)) : bool)
///
@safe unittest
{
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], [] ];
@ -2764,6 +2815,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
&& isForwardRange!Separator
&& (hasLength!Separator || isNarrowString!Separator))
{
import std.algorithm : find; // FIXME
import std.conv : unsigned;
static struct Result
@ -2916,6 +2968,8 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
///
@safe unittest
{
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] ];
@ -2928,6 +2982,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.typecons : Tuple;
alias C = Tuple!(int, "x", int, "y");
@ -2937,6 +2992,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.conv : text;
import std.array : split;
@ -2992,6 +3048,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
@safe unittest
{
import std.algorithm.comparison : equal;
debug(std_algorithm) scope(success)
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
auto s6 = ",";
@ -3005,6 +3062,8 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
@safe unittest
{
import std.algorithm.comparison : equal;
// Issue 10773
auto s = splitter("abc", "");
assert(s.equal(["a", "b", "c"]));
@ -3012,6 +3071,8 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
@safe unittest
{
import std.algorithm.comparison : equal;
// Test by-reference separator
class RefSep {
@safe:
@ -3062,6 +3123,8 @@ if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(input.front))))
///
@safe unittest
{
import std.algorithm.comparison : equal;
assert(equal(splitter!"a == ' '"("hello world"), [ "hello", "", "world" ]));
int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
int[][] w = [ [1, 2], [], [3], [4, 5], [] ];
@ -3076,6 +3139,7 @@ if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(input.front))))
private struct SplitterResult(alias isTerminator, Range)
{
import std.algorithm : find; // FIXME
enum fullSlicing = (hasLength!Range && hasSlicing!Range) || isSomeString!Range;
private Range _input;
@ -3185,6 +3249,7 @@ private struct SplitterResult(alias isTerminator, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range : iota;
auto L = iota(1L, 10L);
@ -3198,6 +3263,8 @@ private struct SplitterResult(alias isTerminator, Range)
@safe unittest
{
import std.algorithm : algoFormat; // FIXME
import std.algorithm.comparison : equal;
import std.internal.test.dummyrange;
debug(std_algorithm) scope(success)
@ -3233,7 +3300,10 @@ private struct SplitterResult(alias isTerminator, Range)
@safe unittest
{
import std.algorithm : algoFormat; // FIXME
import std.algorithm.comparison : equal;
import std.range;
struct Entry
{
int low;
@ -3257,6 +3327,7 @@ private struct SplitterResult(alias isTerminator, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.uni : isWhite;
//@@@6791@@@
@ -3282,6 +3353,7 @@ Returns:
auto splitter(C)(C[] s)
if (isSomeChar!C)
{
import std.algorithm : find; // FIXME
static struct Result
{
private:
@ -3335,12 +3407,15 @@ if (isSomeChar!C)
///
@safe pure unittest
{
import std.algorithm.comparison : equal;
auto a = " a bcd ef gh ";
assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));
}
@safe pure unittest
{
import std.algorithm.comparison : equal;
import std.typetuple : TypeTuple;
foreach(S; TypeTuple!(string, wstring, dstring))
{
import std.conv : to;
@ -3382,6 +3457,8 @@ if (isSomeChar!C)
@safe unittest
{
import std.algorithm : algoFormat; // FIXME
import std.algorithm.comparison : equal;
import std.conv : text;
import std.array : split;
@ -3668,6 +3745,8 @@ if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))
///
@safe unittest
{
import std.algorithm : copy; // FIXME
import std.algorithm.comparison : equal;
int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));
@ -3740,6 +3819,7 @@ private struct UniqResult(alias pred, Range)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.internal.test.dummyrange;
import std.range;

View file

@ -5913,7 +5913,8 @@ assert(arr == [ 1, 3, 4, 5, 4, 5, 2 ]);
Specifies whether the output of certain algorithm is desired in sorted
format.
*/
enum SortOutput {
enum SortOutput
{
no, /// Don't sort output
yes, /// Sort output
}

View file

@ -1,17 +1,12 @@
// Written in the D programming language.
module std.algorithm.setops;
// Ugly hack, while stuff still sits in package.d
private import std.algorithm;
import std.range.primitives;
// FIXME
import std.functional; // : unaryFun, binaryFun;
import std.traits;
// FIXME
import std.typecons; // : tuple, Tuple;
// FIXME
import std.typetuple; // : TypeTuple, staticMap, allSatisfy, anySatisfy;
// cartesianProduct
@ -36,11 +31,14 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
if (!allSatisfy!(isForwardRange, R1, R2) ||
anySatisfy!(isInfinite, R1, R2))
{
import std.algorithm.iteration : map, joiner;
static if (isInfinite!R1 && isInfinite!R2)
{
static if (isForwardRange!R1 && isForwardRange!R2)
{
import std.range : zip, repeat, take, chain, sequence;
// This algorithm traverses the cartesian product by alternately
// covering the right and bottom edges of an increasing square area
// over the infinite table of combinations. This schedule allows us
@ -75,7 +73,9 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
///
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.range;
import std.typecons : tuple;
auto N = sequence!"n"(0); // the range of natural numbers
auto N2 = cartesianProduct(N, N); // the range of all pairs of natural numbers
@ -90,6 +90,9 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
///
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.typecons : tuple;
auto B = [ 1, 2, 3 ];
auto C = [ 4, 5, 6 ];
auto BC = cartesianProduct(B, C);
@ -104,7 +107,10 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
@safe unittest
{
// Test cartesian product of two infinite ranges
import std.algorithm : canFind; // FIXME
import std.range;
import std.typecons : tuple;
auto Even = sequence!"2*n"(0);
auto Odd = sequence!"2*n+1"(0);
auto EvenOdd = cartesianProduct(Even, Odd);
@ -125,7 +131,10 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
{
// Test cartesian product of an infinite input range and a finite forward
// range.
import std.algorithm : canFind; // FIXME
import std.range;
import std.typecons : tuple;
auto N = sequence!"n"(0);
auto M = [100, 200, 300];
auto NM = cartesianProduct(N,M);
@ -160,6 +169,9 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.typecons : tuple;
// Test cartesian product of two finite ranges.
auto X = [1, 2, 3];
auto Y = [4, 5, 6];
@ -184,6 +196,11 @@ auto cartesianProduct(R1, R2)(R1 range1, R2 range2)
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.typecons : tuple;
import std.range;
auto N = sequence!"n"(0);
@ -312,6 +329,7 @@ auto cartesianProduct(RR...)(RR ranges)
}
@property auto front()
{
import std.algorithm : algoFormat; // FIXME
import std.range : iota;
return mixin(algoFormat("tuple(%(current[%d].front%|,%))",
iota(0, current.length)));
@ -385,7 +403,10 @@ auto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)
* one level of tuples so that a ternary cartesian product, for example,
* returns 3-element tuples instead of nested 2-element tuples.
*/
import std.algorithm : algoFormat; // FIXME
import std.algorithm.iteration : map;
import std.range : iota;
enum string denest = algoFormat("tuple(a[0], %(a[1][%d]%|,%))",
iota(0, otherRanges.length+1));
return map!denest(
@ -395,7 +416,10 @@ auto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.range;
import std.typecons : tuple, Tuple;
auto N = sequence!"n"(0);
auto N3 = cartesianProduct(N, N, N);
@ -409,7 +433,10 @@ auto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)
@safe unittest
{
import std.algorithm : canFind; // FIXME
import std.range;
import std.typecons : tuple, Tuple;
auto N = sequence!"n"(0);
auto N4 = cartesianProduct(N, N, N, N);
@ -425,6 +452,9 @@ auto cartesianProduct(R1, R2, RR...)(R1 range1, R2 range2, RR otherRanges)
///
@safe unittest
{
import std.algorithm.comparison : equal;
import std.typecons : tuple;
auto A = [ 1, 2, 3 ];
auto B = [ 'a', 'b', 'c' ];
auto C = [ "x", "y", "z" ];
@ -459,6 +489,7 @@ pure @safe nothrow @nogc unittest
// Issue 13935
unittest
{
import std.algorithm.iteration : map;
auto seq = [1, 2].map!(x => x);
foreach (pair; cartesianProduct(seq, seq)) {}
}
@ -524,6 +555,8 @@ void largestPartialIntersection
sorted);
}
import std.algorithm : SortOutput; // FIXME
// largestPartialIntersectionWeighted
/**
Similar to $(D largestPartialIntersection), but associates a weight
@ -557,6 +590,9 @@ void largestPartialIntersectionWeighted
(alias less = "a < b", RangeOfRanges, Range, WeightsAA)
(RangeOfRanges ror, Range tgt, WeightsAA weights, SortOutput sorted = SortOutput.no)
{
import std.algorithm.iteration : group;
import std.algorithm.sorting : topNCopy;
if (tgt.empty) return;
alias InfoType = ElementType!Range;
bool heapComp(InfoType a, InfoType b)
@ -569,6 +605,7 @@ void largestPartialIntersectionWeighted
unittest
{
import std.conv : text;
import std.typecons : tuple, Tuple;
debug(std_algorithm) scope(success)
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
@ -592,6 +629,7 @@ unittest
unittest
{
import std.conv : text;
import std.typecons : tuple, Tuple;
debug(std_algorithm) scope(success)
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
@ -612,6 +650,8 @@ unittest
unittest
{
import std.typecons : tuple, Tuple;
//scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " done.");
// Figure which number can be found in most arrays of the set of
// arrays below, with specific per-element weights
@ -634,6 +674,7 @@ unittest
unittest
{
import std.container : Array;
import std.typecons : Tuple;
alias T = Tuple!(uint, uint);
const Array!T arrayOne = Array!T( [ T(1,2), T(3,4) ] );
@ -681,6 +722,8 @@ struct NWayUnion(alias less, RangeOfRanges)
this(RangeOfRanges ror)
{
import std.algorithm : remove, SwapStrategy; // FIXME
// Preemptively get rid of all empty ranges in the input
// No need for stability either
_ror = remove!("a.empty", SwapStrategy.unstable)(ror);
@ -723,6 +766,8 @@ NWayUnion!(less, RangeOfRanges) nWayUnion
///
unittest
{
import std.algorithm.comparison : equal;
double[][] a =
[
[ 1, 4, 7, 8 ],
@ -813,6 +858,8 @@ SetDifference!(less, R1, R2) setDifference(alias less = "a < b", R1, R2)
///
@safe unittest
{
import std.algorithm.comparison : equal;
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
assert(equal(setDifference(a, b), [5, 9][]));
@ -821,6 +868,8 @@ SetDifference!(less, R1, R2) setDifference(alias less = "a < b", R1, R2)
@safe unittest // Issue 10460
{
import std.algorithm.comparison : equal;
int[] a = [1, 2, 3, 4, 5];
int[] b = [2, 4];
foreach (ref e; setDifference(a, b))
@ -931,6 +980,8 @@ SetIntersection!(less, Rs) setIntersection(alias less = "a < b", Rs...)(Rs range
///
@safe unittest
{
import std.algorithm.comparison : equal;
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 0, 1, 4, 5, 7, 8 ];
@ -941,6 +992,9 @@ SetIntersection!(less, Rs) setIntersection(alias less = "a < b", Rs...)(Rs range
@safe unittest
{
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter;
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 0, 1, 4, 5, 7, 8 ];
@ -1065,6 +1119,8 @@ setSymmetricDifference(alias less = "a < b", R1, R2)
///
@safe unittest
{
import std.algorithm.comparison : equal;
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][]));
@ -1211,6 +1267,8 @@ SetUnion!(less, Rs) setUnion(alias less = "a < b", Rs...)
///
@safe unittest
{
import std.algorithm.comparison : equal;
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 10 ];

View file

@ -1,16 +1,12 @@
// Written in the D programming language.
module std.algorithm.sorting;
private import std.algorithm; // ugly hack for now
import std.algorithm : SortOutput, SwapStrategy; // FIXME
import std.functional; // : unaryFun, binaryFun;
import std.range.primitives;
// FIXME
import std.range; // : SortedRange;
import std.traits;
// FIXME
import std.typecons; // : tuple, Tuple;
// completeSort
/**
@ -26,6 +22,7 @@ void completeSort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
Range1, Range2)(SortedRange!(Range1, less) lhs, Range2 rhs)
if (hasLength!(Range2) && hasSlicing!(Range2))
{
import std.algorithm : bringToFront; // FIXME
import std.range : chain, assumeSorted;
// Probably this algorithm can be optimized by using in-place
// merge
@ -159,6 +156,7 @@ Range partition(alias predicate,
if ((ss == SwapStrategy.stable && isRandomAccessRange!(Range))
|| (ss != SwapStrategy.stable && isForwardRange!(Range)))
{
import std.algorithm : bringToFront, swap; // FIXME;
alias pred = unaryFun!(predicate);
if (r.empty) return r;
static if (ss == SwapStrategy.stable)
@ -236,6 +234,7 @@ Range partition(alias predicate,
///
@safe unittest
{
import std.algorithm : count, find; // FIXME
import std.conv : text;
auto Arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
@ -273,6 +272,7 @@ Range partition(alias predicate,
@safe unittest
{
import std.algorithm : rndstuff; // FIXME
static bool even(int a) { return (a & 1) == 0; }
// test with random data
@ -333,6 +333,10 @@ if (ss == SwapStrategy.unstable && isRandomAccessRange!Range
// The algorithm is described in "Engineering a sort function" by
// Jon Bentley et al, pp 1257.
import std.algorithm : swap, swapRanges; // FIXME
import std.algorithm.comparison : min;
import std.typecons : tuple;
alias lessFun = binaryFun!less;
size_t i, j, k = r.length, l = k;
@ -449,6 +453,7 @@ makeIndex(
if (isForwardRange!(Range) && isRandomAccessRange!(RangeIndex)
&& is(ElementType!(RangeIndex) : ElementType!(Range)*))
{
import std.algorithm : addressOf; // FIXME
import std.exception : enforce;
// assume collection already ordered
@ -623,7 +628,9 @@ template multiSort(less...) //if (less.length > 1)
@safe unittest
{
import std.algorithm.comparison : equal;
import std.range;
static struct Point { int x, y; }
auto pts1 = [ Point(5, 6), Point(1, 0), Point(5, 7), Point(1, 1), Point(1, 2), Point(0, 1) ];
auto pts2 = [ Point(0, 1), Point(1, 0), Point(1, 1), Point(1, 2), Point(5, 6), Point(5, 7) ];
@ -851,6 +858,7 @@ unittest
unittest
{
import std.algorithm : rndstuff; // FIXME
import std.random : Random, unpredictableSeed, uniform;
import std.uni : toUpper;
@ -910,6 +918,8 @@ unittest
// Unstable sort should complete without an excessive number of predicate calls
// This would suggest it's running in quadratic time
import std.algorithm : swapRanges; // FIXME
// Compilation error if predicate is not static, i.e. a nested function
static uint comp;
static bool pred(size_t a, size_t b)
@ -929,6 +939,8 @@ unittest
}
{
import std.algorithm : swap; // FIXME
bool proxySwapCalled;
struct S
{
@ -950,6 +962,7 @@ unittest
//private
void swapAt(R)(R r, size_t i1, size_t i2)
{
import std.algorithm : swap; // FIXME
static if (is(typeof(&r[i1])))
{
swap(r[i1], r[i2]);
@ -966,6 +979,9 @@ void swapAt(R)(R r, size_t i1, size_t i2)
private void quickSortImpl(alias less, Range)(Range r, size_t depth)
{
import std.algorithm : swap; // FIXME
import std.algorithm.comparison : min;
alias Elem = ElementType!(Range);
enum size_t optimisticInsertionSortGetsBetter = 25;
static assert(optimisticInsertionSortGetsBetter >= 1);
@ -1111,6 +1127,8 @@ private template TimSortImpl(alias pred, R)
// Entry point for tim sort
void sort(R range, T[] temp)
{
import std.algorithm.comparison : min;
// Do insertion sort on small range
if (range.length <= minimalMerge)
{
@ -1202,6 +1220,8 @@ private template TimSortImpl(alias pred, R)
}
body
{
import std.algorithm : reverse; // FIXME
if (range.length < 2) return range.length;
size_t i = 2;
@ -1225,6 +1245,8 @@ private template TimSortImpl(alias pred, R)
}
body
{
import std.algorithm : move; // FIXME
for (; sortedLen < range.length; ++sortedLen)
{
T item = moveAt(range, sortedLen);
@ -1333,6 +1355,8 @@ private template TimSortImpl(alias pred, R)
}
body
{
import std.algorithm : copy; // FIXME
assert(mid <= range.length);
assert(temp.length >= mid);
@ -1414,6 +1438,8 @@ private template TimSortImpl(alias pred, R)
}
body
{
import std.algorithm : copy; // FIXME
assert(mid <= range.length);
assert(temp.length >= range.length - mid);
@ -1601,6 +1627,8 @@ unittest
// Generates data especially for testing sorting with Timsort
static E[] genSampleData(uint seed)
{
import std.algorithm : swap, swapRanges; // FIXME
auto rnd = Random(seed);
E[] arr;
@ -1763,6 +1791,7 @@ schwartzSort(alias transform, alias less = "a < b",
unittest
{
// issue 4909
import std.typecons : Tuple;
Tuple!(char)[] chars;
schwartzSort!"a[0]"(chars);
}
@ -1770,12 +1799,14 @@ unittest
unittest
{
// issue 5924
import std.typecons : Tuple;
Tuple!(char)[] chars;
schwartzSort!((Tuple!(char) c){ return c[0]; })(chars);
}
unittest
{
import std.algorithm.iteration : map;
import std.math : log2;
debug(std_algorithm) scope(success)
@ -1808,6 +1839,7 @@ unittest
unittest
{
import std.algorithm.iteration : map;
import std.math : log2;
debug(std_algorithm) scope(success)
@ -1889,6 +1921,7 @@ void topN(alias less = "a < b",
Range)(Range r, size_t nth)
if (isRandomAccessRange!(Range) && hasLength!Range)
{
import std.algorithm : swap; // FIXME
import std.random : uniform;
static assert(ss == SwapStrategy.unstable,
@ -1931,6 +1964,9 @@ void topN(alias less = "a < b",
@safe unittest
{
import std.algorithm.comparison : max, min;
import std.algorithm.iteration : reduce;
debug(std_algorithm) scope(success)
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
//scope(failure) writeln(stderr, "Failure testing algorithm");
@ -1979,6 +2015,8 @@ void topN(alias less = "a < b",
@safe unittest
{
import std.algorithm.comparison : max, min;
import std.algorithm.iteration : reduce;
import std.random : uniform;
debug(std_algorithm) scope(success)
@ -2116,6 +2154,7 @@ bool nextPermutation(alias less="a < b", BidirectionalRange)
if (isBidirectionalRange!BidirectionalRange &&
hasSwappableElements!BidirectionalRange)
{
import std.algorithm : find, reverse, swap; // FIXME
import std.range : retro, takeExactly;
// Ranges of 0 or 1 element have no distinct permutations.
if (range.empty) return false;
@ -2195,6 +2234,8 @@ bool nextPermutation(alias less="a < b", BidirectionalRange)
@safe unittest
{
import std.algorithm.comparison : equal;
auto a1 = [1, 2, 3, 4];
assert(nextPermutation(a1));
@ -2363,6 +2404,7 @@ bool nextEvenPermutation(alias less="a < b", BidirectionalRange)
if (isBidirectionalRange!BidirectionalRange &&
hasSwappableElements!BidirectionalRange)
{
import std.algorithm : find, reverse, swap; // FIXME
import std.range : retro, takeExactly;
// Ranges of 0 or 1 element have no distinct permutations.
if (range.empty) return false;