removed final from variable declarations

This commit is contained in:
Walter Bright 2008-01-28 07:06:00 +00:00
parent c3d2ffdf9b
commit e5c065b46e
4 changed files with 442 additions and 440 deletions

View file

@ -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

View file

@ -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

View file

@ -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;
} }
} }

View file

@ -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]);
} }
} }