mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
removed final from variable declarations
This commit is contained in:
parent
c3d2ffdf9b
commit
e5c065b46e
4 changed files with 442 additions and 440 deletions
|
@ -972,6 +972,7 @@ class TypeInfo_Struct : TypeInfo
|
||||||
uint m_flags;
|
uint m_flags;
|
||||||
|
|
||||||
const(MemberInfo[]) function(string) xgetMembers;
|
const(MemberInfo[]) function(string) xgetMembers;
|
||||||
|
void function(void*) xdtor;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeInfo_Tuple : TypeInfo
|
class TypeInfo_Tuple : TypeInfo
|
||||||
|
|
1
object.d
1
object.d
|
@ -150,6 +150,7 @@ class TypeInfo_Struct : TypeInfo
|
||||||
uint m_flags;
|
uint m_flags;
|
||||||
|
|
||||||
const(MemberInfo[]) function(string) xgetMembers;
|
const(MemberInfo[]) function(string) xgetMembers;
|
||||||
|
void function(void*) xdtor;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeInfo_Tuple : TypeInfo
|
class TypeInfo_Tuple : TypeInfo
|
||||||
|
|
878
std/algorithm.d
878
std/algorithm.d
|
@ -1,439 +1,439 @@
|
||||||
// Written in the D programming language.
|
// Written in the D programming language.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This module is a port of a growing fragment of the $(D_PARAM
|
This module is a port of a growing fragment of the $(D_PARAM
|
||||||
algorithm) header in Alexander Stepanov's
|
algorithm) header in Alexander Stepanov's
|
||||||
$(LINK2 http://www.sgi.com/tech/stl/,Standard Template Library).
|
$(LINK2 http://www.sgi.com/tech/stl/,Standard Template Library).
|
||||||
|
|
||||||
Macros:
|
Macros:
|
||||||
WIKI = Phobos/StdAlgorithm
|
WIKI = Phobos/StdAlgorithm
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
Andrei Alexandrescu
|
Andrei Alexandrescu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
|
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
|
||||||
* Written by Andrei Alexandrescu, www.erdani.org
|
* Written by Andrei Alexandrescu, www.erdani.org
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
* arising from the use of this software.
|
* arising from the use of this software.
|
||||||
*
|
*
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* o The origin of this software must not be misrepresented; you must not
|
* o The origin of this software must not be misrepresented; you must not
|
||||||
* claim that you wrote the original software. If you use this software
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
* o Altered source versions must be plainly marked as such, and must not
|
* o Altered source versions must be plainly marked as such, and must not
|
||||||
* be misrepresented as being the original software.
|
* be misrepresented as being the original software.
|
||||||
* o This notice may not be removed or altered from any source
|
* o This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module std.algorithm;
|
module std.algorithm;
|
||||||
private import std.stdio;
|
private import std.stdio;
|
||||||
private import std.math;
|
private import std.math;
|
||||||
private import std.random;
|
private import std.random;
|
||||||
private import std.date;
|
private import std.date;
|
||||||
private import std.functional;
|
private import std.functional;
|
||||||
|
|
||||||
/* The iterator-related part below is undocumented and might
|
/* The iterator-related part below is undocumented and might
|
||||||
* change in future releases. Do NOT rely on it.
|
* change in future releases. Do NOT rely on it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template IteratorType(T : U[], U)
|
template IteratorType(T : U[], U)
|
||||||
{
|
{
|
||||||
alias U* IteratorType;
|
alias U* IteratorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
template ElementType(T : U[], U)
|
template ElementType(T : U[], U)
|
||||||
{
|
{
|
||||||
alias U ElementType;
|
alias U ElementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorType!(T[]) begin(T)(T[] range)
|
IteratorType!(T[]) begin(T)(T[] range)
|
||||||
{
|
{
|
||||||
return range.ptr;
|
return range.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementType!(T[]) front(T)(T[] range)
|
ElementType!(T[]) front(T)(T[] range)
|
||||||
{
|
{
|
||||||
assert(range.length);
|
assert(range.length);
|
||||||
return *range.ptr;
|
return *range.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEmpty(T)(T[] range)
|
bool isEmpty(T)(T[] range)
|
||||||
{
|
{
|
||||||
return !range.length;
|
return !range.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorType!(T[]) end(T)(T[] range)
|
IteratorType!(T[]) end(T)(T[] range)
|
||||||
{
|
{
|
||||||
return range.ptr + range.length;
|
return range.ptr + range.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void next(T)(ref T[] range)
|
void next(T)(ref T[] range)
|
||||||
{
|
{
|
||||||
range = range.ptr[1 .. range.length];;
|
range = range.ptr[1 .. range.length];;
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorType!(R) adjacentFind(R, E)(R range)
|
IteratorType!(R) adjacentFind(R, E)(R range)
|
||||||
{
|
{
|
||||||
if (range.isEmpty()) return range.end();
|
if (range.isEmpty()) return range.end();
|
||||||
auto result = range.begin();
|
auto result = range.begin();
|
||||||
range.next();
|
range.next();
|
||||||
if (range.isEmpty()) return range.end();
|
if (range.isEmpty()) return range.end();
|
||||||
for (; !range.isEmpty(); range.next())
|
for (; !range.isEmpty(); range.next())
|
||||||
{
|
{
|
||||||
auto next = range.begin();
|
auto next = range.begin();
|
||||||
if (*result == *next) return result;
|
if (*result == *next) return result;
|
||||||
result = next;
|
result = next;
|
||||||
}
|
}
|
||||||
return range.end();
|
return range.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorType!(Range) find(Range, E)(Range haystack, E needle)
|
IteratorType!(Range) find(Range, E)(Range haystack, E needle)
|
||||||
{
|
{
|
||||||
ElementType!(Range) e;
|
ElementType!(Range) e;
|
||||||
for (; !isEmpty(haystack); next(haystack))
|
for (; !isEmpty(haystack); next(haystack))
|
||||||
{
|
{
|
||||||
if (front(haystack) == needle) break;
|
if (front(haystack) == needle) break;
|
||||||
}
|
}
|
||||||
return begin(haystack);
|
return begin(haystack);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
int[] a = ([ 1, 2, 3 ]).dup;
|
int[] a = ([ 1, 2, 3 ]).dup;
|
||||||
assert(find(a, 5) == a.ptr + a.length);
|
assert(find(a, 5) == a.ptr + a.length);
|
||||||
assert(find(a, 2) == &a[1]);
|
assert(find(a, 2) == &a[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Swaps $(D_PARAM lhs) and $(D_PARAM rhs).
|
Swaps $(D_PARAM lhs) and $(D_PARAM rhs).
|
||||||
*/
|
*/
|
||||||
void swap(T)(ref T lhs, ref T rhs)
|
void swap(T)(ref T lhs, ref T rhs)
|
||||||
{
|
{
|
||||||
final t = lhs;
|
auto t = lhs;
|
||||||
lhs = rhs;
|
lhs = rhs;
|
||||||
rhs = t;
|
rhs = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Implements C.A.R. Hoare's
|
Implements C.A.R. Hoare's
|
||||||
$(LINK2 http://en.wikipedia.org/wiki/Selection_algorithm#Partition-based_general_selection_algorithm,
|
$(LINK2 http://en.wikipedia.org/wiki/Selection_algorithm#Partition-based_general_selection_algorithm,
|
||||||
partition) algorithm. Specifically, reorders the range [$(D_PARAM
|
partition) algorithm. Specifically, reorders the range [$(D_PARAM
|
||||||
left), $(D_PARAM right)$(RPAREN) such that everything strictly smaller
|
left), $(D_PARAM right)$(RPAREN) such that everything strictly smaller
|
||||||
(according to the predicate $(D_PARAM compare)) than $(D_PARAM *mid)
|
(according to the predicate $(D_PARAM compare)) than $(D_PARAM *mid)
|
||||||
is to the left of the returned pointer, and everything else is at the
|
is to the left of the returned pointer, and everything else is at the
|
||||||
right of the returned pointer.
|
right of the returned pointer.
|
||||||
|
|
||||||
Precondition:
|
Precondition:
|
||||||
|
|
||||||
$(D_PARAM left == mid && mid == right
|
$(D_PARAM left == mid && mid == right
|
||||||
||
|
||
|
||||||
left <= mid && mid < right).
|
left <= mid && mid < right).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
If $(D_PARAM left == right), returns $(D_PARAM left). Otherwise,
|
If $(D_PARAM left == right), returns $(D_PARAM left). Otherwise,
|
||||||
return a value $(D_PARAM p) such that the following three conditions
|
return a value $(D_PARAM p) such that the following three conditions
|
||||||
are simultaneously true:
|
are simultaneously true:
|
||||||
$(OL
|
$(OL
|
||||||
$(LI $(D_PARAM *p == *mid))
|
$(LI $(D_PARAM *p == *mid))
|
||||||
$(LI $(D_PARAM compare(*p1, *p)) for all $(D_PARAM p1) in [$(D_PARAM
|
$(LI $(D_PARAM compare(*p1, *p)) for all $(D_PARAM p1) in [$(D_PARAM
|
||||||
left), $(D_PARAM p)$(RPAREN))
|
left), $(D_PARAM p)$(RPAREN))
|
||||||
$(LI $(D_PARAM !compare(*p2, *p)) for all $(D_PARAM p2) in [$(D_PARAM p),
|
$(LI $(D_PARAM !compare(*p2, *p)) for all $(D_PARAM p2) in [$(D_PARAM p),
|
||||||
$(D_PARAM right)$(RPAREN)))
|
$(D_PARAM right)$(RPAREN)))
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
----
|
----
|
||||||
auto a = [3, 3, 2].dup;
|
auto a = [3, 3, 2].dup;
|
||||||
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
||||||
assert(p == a.ptr + 1 && a == [2, 3, 3]);
|
assert(p == a.ptr + 1 && a == [2, 3, 3]);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
template partition(alias compare)
|
template partition(alias compare)
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
T partition(T)(T left, T mid, T right)
|
T partition(T)(T left, T mid, T right)
|
||||||
{
|
{
|
||||||
if (left == right) return left;
|
if (left == right) return left;
|
||||||
assert(left <= mid && mid < right);
|
assert(left <= mid && mid < right);
|
||||||
auto pivot = *mid;
|
auto pivot = *mid;
|
||||||
--right;
|
--right;
|
||||||
swap(*mid, *right); // Move pivot to end
|
swap(*mid, *right); // Move pivot to end
|
||||||
auto result = left;
|
auto result = left;
|
||||||
for (auto i = left; i != right; ++i) {
|
for (auto i = left; i != right; ++i) {
|
||||||
if (!compare(*i, pivot)) continue;
|
if (!compare(*i, pivot)) continue;
|
||||||
swap(*result, *i);
|
swap(*result, *i);
|
||||||
++result;
|
++result;
|
||||||
}
|
}
|
||||||
swap(*right, *result); // Move pivot to its final place
|
swap(*right, *result); // Move pivot to its final place
|
||||||
assert(*result == pivot);
|
assert(*result == pivot);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
int[] a = null;
|
int[] a = null;
|
||||||
auto p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
auto p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
||||||
assert(p is null);
|
assert(p is null);
|
||||||
|
|
||||||
a = [2].dup;
|
a = [2].dup;
|
||||||
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
||||||
assert(p == a.ptr);
|
assert(p == a.ptr);
|
||||||
|
|
||||||
a = [2, 2].dup;
|
a = [2, 2].dup;
|
||||||
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
||||||
assert(p == a.ptr);
|
assert(p == a.ptr);
|
||||||
|
|
||||||
p = partition!(less)(a.ptr, a.ptr + 1, a.ptr + a.length);
|
p = partition!(less)(a.ptr, a.ptr + 1, a.ptr + a.length);
|
||||||
assert(p == a.ptr);
|
assert(p == a.ptr);
|
||||||
|
|
||||||
a = [3, 3, 2].dup;
|
a = [3, 3, 2].dup;
|
||||||
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
p = partition!(less)(a.ptr, a.ptr, a.ptr + a.length);
|
||||||
assert(p == a.ptr + 1);
|
assert(p == a.ptr + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reorders the range [$(D_PARAM b), $(D_PARAM e)$(RPAREN) such that
|
Reorders the range [$(D_PARAM b), $(D_PARAM e)$(RPAREN) such that
|
||||||
$(D_PARAM nth) points to the element that would fall there if the
|
$(D_PARAM nth) points to the element that would fall there if the
|
||||||
range were fully sorted. Effectively, it finds the nth smallest
|
range were fully sorted. Effectively, it finds the nth smallest
|
||||||
(according to $(D_PARAM compare)) element in the range [$(D_PARAM b),
|
(according to $(D_PARAM compare)) element in the range [$(D_PARAM b),
|
||||||
$(D_PARAM e)$(RPAREN).
|
$(D_PARAM e)$(RPAREN).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
----
|
----
|
||||||
auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup;
|
auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup;
|
||||||
auto n = 4;
|
auto n = 4;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 9);
|
assert(v[n] == 9);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
template nthElement(alias compare)
|
template nthElement(alias compare)
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
void nthElement(T)(T b, T nth, T e)
|
void nthElement(T)(T b, T nth, T e)
|
||||||
{
|
{
|
||||||
assert(b <= nth && nth < e);
|
assert(b <= nth && nth < e);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto pivot = b + (e - b) / 2;
|
auto pivot = b + (e - b) / 2;
|
||||||
pivot = partition!(compare)(b, pivot, e);
|
pivot = partition!(compare)(b, pivot, e);
|
||||||
if (pivot == nth) return;
|
if (pivot == nth) return;
|
||||||
if (pivot < nth) b = pivot + 1;
|
if (pivot < nth) b = pivot + 1;
|
||||||
else e = pivot;
|
else e = pivot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
scope(failure) writeln(stderr, "Failure testing algorithm");
|
scope(failure) writeln(stderr, "Failure testing algorithm");
|
||||||
auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup;
|
auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup;
|
||||||
auto n = 4;
|
auto n = 4;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 9);
|
assert(v[n] == 9);
|
||||||
//
|
//
|
||||||
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
||||||
n = 3;
|
n = 3;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 3);
|
assert(v[n] == 3);
|
||||||
//
|
//
|
||||||
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
||||||
n = 1;
|
n = 1;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 2);
|
assert(v[n] == 2);
|
||||||
//
|
//
|
||||||
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
||||||
n = v.length - 1;
|
n = v.length - 1;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 7);
|
assert(v[n] == 7);
|
||||||
//
|
//
|
||||||
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
v = ([3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5]).dup;
|
||||||
n = 0;
|
n = 0;
|
||||||
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
nthElement!(less)(v.ptr, v.ptr + n, v.ptr + v.length);
|
||||||
assert(v[n] == 1);
|
assert(v[n] == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reverses $(D_PARAM range) in-place.
|
Reverses $(D_PARAM range) in-place.
|
||||||
*/
|
*/
|
||||||
void reverse(T)(T range)
|
void reverse(T)(T range)
|
||||||
{
|
{
|
||||||
auto len = range.length;
|
auto len = range.length;
|
||||||
final limit = len / 2;
|
const limit = len / 2;
|
||||||
--len;
|
--len;
|
||||||
for (uint i = 0; i != limit; ++i)
|
for (uint i = 0; i != limit; ++i)
|
||||||
{
|
{
|
||||||
final t = range[i];
|
auto t = range[i];
|
||||||
range[i] = range[len - i];
|
range[i] = range[len - i];
|
||||||
range[len - i] = t;
|
range[len - i] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
int[] range = null;
|
int[] range = null;
|
||||||
reverse(range);
|
reverse(range);
|
||||||
range = [ 1 ].dup;
|
range = [ 1 ].dup;
|
||||||
reverse(range);
|
reverse(range);
|
||||||
assert(range == [1]);
|
assert(range == [1]);
|
||||||
range = [1, 2].dup;
|
range = [1, 2].dup;
|
||||||
reverse(range);
|
reverse(range);
|
||||||
assert(range == [2, 1]);
|
assert(range == [2, 1]);
|
||||||
range = [1, 2, 3].dup;
|
range = [1, 2, 3].dup;
|
||||||
reverse(range);
|
reverse(range);
|
||||||
assert(range == [3, 2, 1]);
|
assert(range == [3, 2, 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sorts a random-access range according to predicate $(D_PARAM comp),
|
Sorts a random-access range according to predicate $(D_PARAM comp),
|
||||||
which must be a function name.
|
which must be a function name.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
----
|
----
|
||||||
int[] array = ([ 1, 2, 3, 4 ]).dup;
|
int[] array = ([ 1, 2, 3, 4 ]).dup;
|
||||||
sort!(greater)(array);
|
sort!(greater)(array);
|
||||||
assert(array == [ 4, 3, 2, 1 ]);
|
assert(array == [ 4, 3, 2, 1 ]);
|
||||||
bool myComp(int x, int y) { return x < y; }
|
bool myComp(int x, int y) { return x < y; }
|
||||||
sort!(myComp)(array);
|
sort!(myComp)(array);
|
||||||
assert(array == [ 1, 2, 3, 4 ]);
|
assert(array == [ 1, 2, 3, 4 ]);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template sort(alias comp)
|
template sort(alias comp)
|
||||||
{
|
{
|
||||||
void sort(Range)(Range r)
|
void sort(Range)(Range r)
|
||||||
{
|
{
|
||||||
static if (is(typeof(comp(*begin(r), *end(r))) == bool))
|
static if (is(typeof(comp(*begin(r), *end(r))) == bool))
|
||||||
{
|
{
|
||||||
sortImpl!(comp)(begin(r), end(r));
|
sortImpl!(comp)(begin(r), end(r));
|
||||||
assert(isSorted!(comp)(r));
|
assert(isSorted!(comp)(r));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static assert(false, typeof(&comp).stringof);
|
static assert(false, typeof(&comp).stringof);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sorts a random-access range according to predicate $(D_PARAM comp),
|
Sorts a random-access range according to predicate $(D_PARAM comp),
|
||||||
expressed as a string. The string can use the names "a" and "b" for
|
expressed as a string. The string can use the names "a" and "b" for
|
||||||
the two elements being compared.
|
the two elements being compared.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
----
|
----
|
||||||
int[] array = ([ 1, 2, 3, 4 ]).dup;
|
int[] array = ([ 1, 2, 3, 4 ]).dup;
|
||||||
sort!("a > b")(array);
|
sort!("a > b")(array);
|
||||||
assert(array == [ 4, 3, 2, 1 ]);
|
assert(array == [ 4, 3, 2, 1 ]);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template sort(string comp)
|
template sort(string comp)
|
||||||
{
|
{
|
||||||
void sort(Range)(Range r)
|
void sort(Range)(Range r)
|
||||||
{
|
{
|
||||||
alias typeof(*begin(r)) ElementType;
|
alias typeof(*begin(r)) ElementType;
|
||||||
static ElementType a, b;
|
static ElementType a, b;
|
||||||
alias typeof(mixin(comp)) ResultType;
|
alias typeof(mixin(comp)) ResultType;
|
||||||
static ResultType compFn(ElementType a, ElementType b)
|
static ResultType compFn(ElementType a, ElementType b)
|
||||||
{
|
{
|
||||||
return mixin(comp);
|
return mixin(comp);
|
||||||
}
|
}
|
||||||
.sort!(compFn)(r);
|
.sort!(compFn)(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
// sort using delegate
|
// sort using delegate
|
||||||
int a[] = new int[100];
|
int a[] = new int[100];
|
||||||
auto rnd = Random(getUTCtime);
|
auto rnd = Random(getUTCtime);
|
||||||
foreach (ref e; a) {
|
foreach (ref e; a) {
|
||||||
e = uniform!(int)(rnd, -100, 100);
|
e = uniform!(int)(rnd, -100, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool greater2(int a, int b) { return a + i > b + i; }
|
bool greater2(int a, int b) { return a + i > b + i; }
|
||||||
bool delegate(int, int) greater = &greater2;
|
bool delegate(int, int) greater = &greater2;
|
||||||
sort!(greater)(a);
|
sort!(greater)(a);
|
||||||
assert(isSorted!(greater)(a));
|
assert(isSorted!(greater)(a));
|
||||||
|
|
||||||
// sort using string
|
// sort using string
|
||||||
sort!("a < b")(a);
|
sort!("a < b")(a);
|
||||||
assert(isSorted!(less)(a));
|
assert(isSorted!(less)(a));
|
||||||
|
|
||||||
// sort using function; all elements equal
|
// sort using function; all elements equal
|
||||||
foreach (ref e; a) {
|
foreach (ref e; a) {
|
||||||
e = 5;
|
e = 5;
|
||||||
}
|
}
|
||||||
sort!(less)(a);
|
sort!(less)(a);
|
||||||
assert(isSorted!(less)(a));
|
assert(isSorted!(less)(a));
|
||||||
|
|
||||||
// sort using ternary predicate
|
// sort using ternary predicate
|
||||||
//sort!("b - a")(a);
|
//sort!("b - a")(a);
|
||||||
//assert(isSorted!(less)(a));
|
//assert(isSorted!(less)(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private*/ template getPivot(alias compare)
|
/*private*/ template getPivot(alias compare)
|
||||||
{
|
{
|
||||||
Iter getPivot(Iter)(Iter b, Iter e)
|
Iter getPivot(Iter)(Iter b, Iter e)
|
||||||
{
|
{
|
||||||
final r = b + (e - b) / 2;
|
auto r = b + (e - b) / 2;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private*/ template sortImpl(alias comp)
|
/*private*/ template sortImpl(alias comp)
|
||||||
{
|
{
|
||||||
void sortImpl(Iter)(Iter b, Iter e)
|
void sortImpl(Iter)(Iter b, Iter e)
|
||||||
{
|
{
|
||||||
while (e - b > 1)
|
while (e - b > 1)
|
||||||
{
|
{
|
||||||
auto m = partition!(comp)(b, getPivot!(comp)(b, e), e);
|
auto m = partition!(comp)(b, getPivot!(comp)(b, e), e);
|
||||||
assert(b <= m && m < e);
|
assert(b <= m && m < e);
|
||||||
.sortImpl!(comp)(b, m);
|
.sortImpl!(comp)(b, m);
|
||||||
b = ++m;
|
b = ++m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks whether a random-access range is sorted according to the
|
Checks whether a random-access range is sorted according to the
|
||||||
comparison operation $(D_PARAM comp).
|
comparison operation $(D_PARAM comp).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
----
|
----
|
||||||
int[] arr = ([4, 3, 2, 1]).dup;
|
int[] arr = ([4, 3, 2, 1]).dup;
|
||||||
assert(!isSorted!(less)(arr));
|
assert(!isSorted!(less)(arr));
|
||||||
sort!(less)(arr);
|
sort!(less)(arr);
|
||||||
assert(isSorted!(less)(arr));
|
assert(isSorted!(less)(arr));
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template isSorted(alias comp)
|
template isSorted(alias comp)
|
||||||
{
|
{
|
||||||
bool isSorted(Range)(Range r)
|
bool isSorted(Range)(Range r)
|
||||||
{
|
{
|
||||||
auto b = begin(r), e = end(r);
|
auto b = begin(r), e = end(r);
|
||||||
if (e - b <= 1) return true;
|
if (e - b <= 1) return true;
|
||||||
auto next = b + 1;
|
auto next = b + 1;
|
||||||
for (; next < e; ++b, ++next) {
|
for (; next < e; ++b, ++next) {
|
||||||
if (comp(*next, *b)) return false;
|
if (comp(*next, *b)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ void randomShuffle(T, SomeRandomGen)(T[] array, ref SomeRandomGen r)
|
||||||
foreach (i; 0 .. array.length)
|
foreach (i; 0 .. array.length)
|
||||||
{
|
{
|
||||||
// generate a random number i .. n
|
// generate a random number i .. n
|
||||||
final which = i + uniform!(size_t)(r, 0u, array.length - i);
|
auto which = i + uniform!(size_t)(r, 0u, array.length - i);
|
||||||
swap(array[i], array[which]);
|
swap(array[i], array[which]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue