mirror of
https://github.com/dlang/phobos.git
synced 2025-05-03 08:30:33 +03:00
Moved join from std.string to std.array, plus a few cosmetic changes
This commit is contained in:
parent
a0ecf2a10e
commit
cf33c1999a
4 changed files with 175 additions and 191 deletions
|
@ -1853,10 +1853,18 @@ unittest
|
||||||
|
|
||||||
// joiner
|
// joiner
|
||||||
/**
|
/**
|
||||||
Lazily joins a range of ranges with a separator. The range of ranges
|
Lazily joins a range of ranges with a separator. The separator itself
|
||||||
|
is a range.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
----
|
----
|
||||||
|
assert(equal(joiner([""], "xyz"), ""));
|
||||||
|
assert(equal(joiner(["", ""], "xyz"), "xyz"));
|
||||||
|
assert(equal(joiner(["", "abc"], "xyz"), "xyzabc"));
|
||||||
|
assert(equal(joiner(["abc", ""], "xyz"), "abcxyz"));
|
||||||
|
assert(equal(joiner(["abc", "def"], "xyz"), "abcxyzdef"));
|
||||||
|
assert(equal(joiner(["Mary", "has", "a", "little", "lamb"], "..."),
|
||||||
|
"Mary...has...a...little...lamb"));
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
auto joiner(Range, Separator)(Range r, Separator sep)
|
auto joiner(Range, Separator)(Range r, Separator sep)
|
||||||
|
|
216
std/array.d
216
std/array.d
|
@ -19,7 +19,7 @@ import std.algorithm, std.conv, std.encoding, std.exception, std.range,
|
||||||
std.string, std.traits, std.typecons, std.utf;
|
std.string, std.traits, std.typecons, std.utf;
|
||||||
private import std.c.string : memcpy;
|
private import std.c.string : memcpy;
|
||||||
private import std.intrinsic : bsr;
|
private import std.intrinsic : bsr;
|
||||||
version(unittest) private import std.stdio;
|
version(unittest) private import std.stdio, std.typetuple;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a newly-allocated dynamic array consisting of a copy of the input
|
Returns a newly-allocated dynamic array consisting of a copy of the input
|
||||||
|
@ -77,39 +77,6 @@ if (isIterable!Range && !isNarrowString!Range)
|
||||||
}
|
}
|
||||||
return a.data;
|
return a.data;
|
||||||
}
|
}
|
||||||
// // 2. Initialize the memory
|
|
||||||
// size_t constructedElements = 0;
|
|
||||||
// scope(failure)
|
|
||||||
// {
|
|
||||||
// // Deconstruct only what was constructed
|
|
||||||
// foreach_reverse (i; 0 .. constructedElements)
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// //result[i].~E();
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // free the entire array
|
|
||||||
// std.gc.realloc(result, 0);
|
|
||||||
// }
|
|
||||||
// foreach (src; elements)
|
|
||||||
// {
|
|
||||||
// static if (is(typeof(new(result + constructedElements) E(src))))
|
|
||||||
// {
|
|
||||||
// new(result + constructedElements) E(src);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// result[constructedElements] = src;
|
|
||||||
// }
|
|
||||||
// ++constructedElements;
|
|
||||||
// }
|
|
||||||
// // 3. Success constructing all elements, type the array and return it
|
|
||||||
// setTypeInfo(typeid(E), result);
|
|
||||||
// return result[0 .. constructedElements];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,17 +162,6 @@ unittest
|
||||||
assert(array("ABC".dup) == "ABC"d.dup);
|
assert(array("ABC".dup) == "ABC"d.dup);
|
||||||
}
|
}
|
||||||
|
|
||||||
template IndexType(C : T[], T)
|
|
||||||
{
|
|
||||||
alias size_t IndexType;
|
|
||||||
}
|
|
||||||
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
static assert(is(IndexType!(double[]) == size_t));
|
|
||||||
static assert(!is(IndexType!(double) == size_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Implements the range interface primitive $(D empty) for built-in
|
Implements the range interface primitive $(D empty) for built-in
|
||||||
arrays. Due to the fact that nonmember functions can be called with
|
arrays. Due to the fact that nonmember functions can be called with
|
||||||
|
@ -628,41 +584,149 @@ bool sameHead(T)(in T[] lhs, in T[] rhs)
|
||||||
return lhs.ptr == rhs.ptr;
|
return lhs.ptr == rhs.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/********************************************
|
||||||
Erases elements from $(D array) with indices ranging from $(D from)
|
* Return an array that consists of $(D s) (which must be an input
|
||||||
(inclusive) to $(D to) (exclusive).
|
* range) repeated $(D n) times.
|
||||||
*/
|
*/
|
||||||
// void erase(T)(ref T[] array, size_t from, size_t to)
|
|
||||||
// {
|
|
||||||
// immutable newLength = array.length - (to - from);
|
|
||||||
// foreach (i; to .. array.length)
|
|
||||||
// {
|
|
||||||
// move(array[i], array[from++]);
|
|
||||||
// }
|
|
||||||
// array.length = newLength;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// unittest
|
S multiply(S)(S s, size_t n) if (isSomeString!S)
|
||||||
// {
|
{
|
||||||
// int[] a = [1, 2, 3, 4, 5];
|
if (n == 0)
|
||||||
// erase(a, 1u, 3u);
|
return S.init;
|
||||||
// assert(a == [1, 4, 5]);
|
if (n == 1)
|
||||||
// }
|
return s;
|
||||||
|
auto r = new Unqual!(typeof(s[0]))[n * s.length];
|
||||||
|
if (s.length == 1)
|
||||||
|
r[] = s[0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto len = s.length;
|
||||||
|
for (size_t i = 0; i < n * len; i += len)
|
||||||
|
{
|
||||||
|
r[i .. i + len] = s[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cast(S) r;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
ElementType!S[] multiply(S)(S s, size_t n)
|
||||||
Erases element from $(D array) at index $(D from).
|
if (isInputRange!S && !isSomeString!S)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
return null;
|
||||||
|
static if (hasLength!S)
|
||||||
|
{
|
||||||
|
auto r = new Unqual!(typeof(s[0]))[n * s.length];
|
||||||
|
if (s.length == 1)
|
||||||
|
r[] = s[0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto len = s.length;
|
||||||
|
immutable nlen = n * len;
|
||||||
|
for (size_t i = 0; i < nlen; i += len)
|
||||||
|
{
|
||||||
|
copy(s, r[i .. i + len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cast(typeof(return)) r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Appender!(ElementType!S) a;
|
||||||
|
for (; !s.empty; s.popFront())
|
||||||
|
{
|
||||||
|
a.put(s.front);
|
||||||
|
}
|
||||||
|
return a.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
debug(string) printf("array.repeat.unittest\n");
|
||||||
|
|
||||||
|
foreach (S; TypeTuple!(string, wstring, dstring, char[], wchar[], dchar[]))
|
||||||
|
{
|
||||||
|
S s;
|
||||||
|
|
||||||
|
s = multiply(to!S("1234"), 0);
|
||||||
|
assert(s is null);
|
||||||
|
s = multiply(to!S("1234"), 1);
|
||||||
|
assert(cmp(s, "1234") == 0);
|
||||||
|
s = multiply(to!S("1234"), 2);
|
||||||
|
assert(cmp(s, "12341234") == 0);
|
||||||
|
s = multiply(to!S("1"), 4);
|
||||||
|
assert(cmp(s, "1111") == 0);
|
||||||
|
s = multiply(cast(S) null, 4);
|
||||||
|
assert(s is null);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] a = [ 1, 2, 3 ];
|
||||||
|
assert(multiply(a, 3) == [1, 2, 3, 1, 2, 3, 1, 2, 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************
|
||||||
|
* Concatenate all the ranges in $(D ror) together into one array;
|
||||||
|
* use $(D sep) as the separator.
|
||||||
*/
|
*/
|
||||||
// void erase(T)(ref T[] array, size_t from)
|
|
||||||
// {
|
|
||||||
// erase(array, from, from + 1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// unittest
|
ElementType!RoR join(RoR, R)(RoR ror, R sep)
|
||||||
// {
|
if (isInputRange!RoR && isInputRange!(typeof(ror.front))
|
||||||
// int[] a = [1, 2, 3, 4, 5];
|
&& !(isSomeString!(typeof(ror.front)) && isSomeString!R))
|
||||||
// erase(a, 2u);
|
{
|
||||||
// assert(a == [1, 2, 4, 5]);
|
return copy(joiner(ror, sep), appender!(ElementType!RoR)()).data;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// Specialization for strings
|
||||||
|
typeof(RoR.init[0]) join(RoR, R)(RoR words, R sep)
|
||||||
|
if (isSomeString!(typeof(words[0])) && isSomeString!R)
|
||||||
|
{
|
||||||
|
if (!words.length) return null;
|
||||||
|
auto sep2 = to!(typeof(return))(sep);
|
||||||
|
immutable seplen = sep2.length;
|
||||||
|
size_t len = (words.length - 1) * seplen;
|
||||||
|
|
||||||
|
foreach (i; 0 .. words.length)
|
||||||
|
len += words[i].length;
|
||||||
|
|
||||||
|
auto result = new Unqual!(typeof(words.front[0]))[len];
|
||||||
|
|
||||||
|
size_t j;
|
||||||
|
foreach (i; 0 .. words.length)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
result[j .. j + seplen] = sep2;
|
||||||
|
j += seplen;
|
||||||
|
}
|
||||||
|
immutable wlen = words[i].length;
|
||||||
|
result[j .. j + wlen] = words[i];
|
||||||
|
j += wlen;
|
||||||
|
}
|
||||||
|
assert(j == len);
|
||||||
|
return cast(typeof(return)) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
debug(std_array) printf("array.join.unittest\n");
|
||||||
|
|
||||||
|
string word1 = "peter";
|
||||||
|
string word2 = "paul";
|
||||||
|
string word3 = "jerry";
|
||||||
|
string[3] words;
|
||||||
|
string r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
words[0] = word1;
|
||||||
|
words[1] = word2;
|
||||||
|
words[2] = word3;
|
||||||
|
r = join(words[], ",");
|
||||||
|
i = cmp(r, "peter,paul,jerry");
|
||||||
|
assert(i == 0, text(i));
|
||||||
|
|
||||||
|
assert(join([[1, 2], [41, 42]], [5, 6]) == [1, 2, 5, 6, 41, 42]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Replaces elements from $(D array) with indices ranging from $(D from)
|
Replaces elements from $(D array) with indices ranging from $(D from)
|
||||||
|
@ -704,8 +768,6 @@ void replace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff)
|
||||||
replace(array, from, to, cast(T[])[]);
|
replace(array, from, to, cast(T[])[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
int[] a = [1, 4, 5];
|
int[] a = [1, 4, 5];
|
||||||
|
|
31
std/range.d
31
std/range.d
|
@ -2460,17 +2460,23 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Replicates $(D value) exactly $(D n) times. Equivalent to $(D
|
Repeats $(D value) exactly $(D n) times. Equivalent to $(D
|
||||||
take(repeat(value), n)).
|
take(repeat(value), n)).
|
||||||
*/
|
*/
|
||||||
Take!(Repeat!(T)) replicate(T)(T value, size_t n)
|
Take!(Repeat!T) repeat(T)(T value, size_t n)
|
||||||
{
|
{
|
||||||
return take(repeat(value), n);
|
return take(repeat(value), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Equivalent to $(D repeat(value, n)). Scheduled for deprecation.
|
||||||
|
Take!(Repeat!T) replicate(T)(T value, size_t n)
|
||||||
|
{
|
||||||
|
return repeat(value, n);
|
||||||
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
enforce(equal(replicate(5, 4), [ 5, 5, 5, 5 ][]));
|
enforce(equal(repeat(5, 4), [ 5, 5, 5, 5 ][]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2559,24 +2565,23 @@ if (isForwardRange!(Unqual!Range) && !isInfinite!(Unqual!Range))
|
||||||
if (_current.empty) _current = _original;
|
if (_current.empty) _current = _original;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property Cycle!(R) save() {
|
@property Cycle!R save() {
|
||||||
Cycle!(R) ret;
|
Cycle!R ret;
|
||||||
ret._original = this._original.save;
|
ret._original = this._original.save;
|
||||||
ret._current = this._current.save;
|
ret._current = this._current.save;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
template Cycle(R) if(isInfinite!(R))
|
template Cycle(R) if (isInfinite!R)
|
||||||
{
|
{
|
||||||
alias R Cycle;
|
alias R Cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
struct Cycle(R) if (isStaticArray!(R))
|
struct Cycle(R) if (isStaticArray!R)
|
||||||
{
|
{
|
||||||
private alias typeof(R[0]) ElementType;
|
private alias typeof(R[0]) ElementType;
|
||||||
private ElementType* _ptr;
|
private ElementType* _ptr;
|
||||||
|
@ -2607,17 +2612,17 @@ struct Cycle(R) if (isStaticArray!(R))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
Cycle!(R) cycle(R)(R input)
|
Cycle!R cycle(R)(R input)
|
||||||
if(isForwardRange!(Unqual!R) && !isInfinite!(Unqual!R))
|
if (isForwardRange!(Unqual!R) && !isInfinite!(Unqual!R))
|
||||||
{
|
{
|
||||||
return Cycle!(R)(input);
|
return Cycle!(R)(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
Cycle!(R) cycle(R)(R input, size_t index)
|
Cycle!R cycle(R)(R input, size_t index)
|
||||||
if(isRandomAccessRange!(Unqual!R) && !isInfinite!(Unqual!R))
|
if (isRandomAccessRange!(Unqual!R) && !isInfinite!(Unqual!R))
|
||||||
{
|
{
|
||||||
return Cycle!(R)(input, index);
|
return Cycle!R(input, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
|
|
109
std/string.d
109
std/string.d
|
@ -172,7 +172,8 @@ unittest
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
* Convert array of chars $(D s[]) to a C-style 0-terminated string.
|
* Convert array of chars $(D s[]) to a C-style 0-terminated string.
|
||||||
* $(D s[]) must not contain embedded 0's.
|
* $(D s[]) must not contain embedded 0's. If $(D s) is $(D null) or
|
||||||
|
* empty, a string containing only $(D '\0') is returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
immutable(char)* toStringz(const(char)[] s)
|
immutable(char)* toStringz(const(char)[] s)
|
||||||
|
@ -194,8 +195,6 @@ out (result)
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
char[] copy;
|
|
||||||
|
|
||||||
/+ Unfortunately, this isn't reliable.
|
/+ Unfortunately, this isn't reliable.
|
||||||
We could make this work if string literals are put
|
We could make this work if string literals are put
|
||||||
in read-only memory and we test if s[] is pointing into
|
in read-only memory and we test if s[] is pointing into
|
||||||
|
@ -212,7 +211,7 @@ body
|
||||||
+/
|
+/
|
||||||
|
|
||||||
// Need to make a copy
|
// Need to make a copy
|
||||||
copy = new char[s.length + 1];
|
auto copy = new char[s.length + 1];
|
||||||
copy[0..s.length] = s;
|
copy[0..s.length] = s;
|
||||||
copy[s.length] = 0;
|
copy[s.length] = 0;
|
||||||
|
|
||||||
|
@ -222,7 +221,7 @@ body
|
||||||
/// Ditto
|
/// Ditto
|
||||||
immutable(char)* toStringz(string s)
|
immutable(char)* toStringz(string s)
|
||||||
{
|
{
|
||||||
if (!s) return null;
|
if (s.empty) return "".ptr;
|
||||||
/* Peek past end of s[], if it's 0, no conversion necessary.
|
/* Peek past end of s[], if it's 0, no conversion necessary.
|
||||||
* Note that the compiler will put a 0 past the end of static
|
* Note that the compiler will put a 0 past the end of static
|
||||||
* strings, and the storage allocator will put a 0 past the end
|
* strings, and the storage allocator will put a 0 past the end
|
||||||
|
@ -359,12 +358,10 @@ unittest
|
||||||
{
|
{
|
||||||
debug(string) printf("string.indexOf.unittest\n");
|
debug(string) printf("string.indexOf.unittest\n");
|
||||||
|
|
||||||
sizediff_t i;
|
|
||||||
|
|
||||||
foreach (S; TypeTuple!(string, wstring, dstring))
|
foreach (S; TypeTuple!(string, wstring, dstring))
|
||||||
{
|
{
|
||||||
S s = null;
|
S s = null;
|
||||||
i = indexOf(s, cast(dchar)'a', CaseSensitive.no);
|
auto i = indexOf(s, cast(dchar)'a', CaseSensitive.no);
|
||||||
assert(i == -1);
|
assert(i == -1);
|
||||||
i = indexOf("def", cast(dchar)'a', CaseSensitive.no);
|
i = indexOf("def", cast(dchar)'a', CaseSensitive.no);
|
||||||
assert(i == -1);
|
assert(i == -1);
|
||||||
|
@ -765,46 +762,6 @@ S tolower(S)(S s) if (isSomeString!S)
|
||||||
return cast(S) result;
|
return cast(S) result;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
/*
|
|
||||||
foreach (i; 0 .. s.length)
|
|
||||||
{
|
|
||||||
auto c = s[i];
|
|
||||||
if ('A' <= c && c <= 'Z')
|
|
||||||
{
|
|
||||||
if (!changed)
|
|
||||||
{
|
|
||||||
r = s.dup;
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
r[i] = cast(Unqual!Char) (c + ('a' - 'A'));
|
|
||||||
}
|
|
||||||
else if (c > 0x7F)
|
|
||||||
{
|
|
||||||
foreach (size_t j, dchar dc; s[i .. $])
|
|
||||||
{
|
|
||||||
if (std.uni.isUniUpper(dc))
|
|
||||||
{
|
|
||||||
dc = std.uni.toUniLower(dc);
|
|
||||||
if (!changed)
|
|
||||||
{
|
|
||||||
r = s[0 .. i + j].dup;
|
|
||||||
changed = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
if (changed == 1)
|
|
||||||
{ r = r[0 .. i + j];
|
|
||||||
changed = 2;
|
|
||||||
}
|
|
||||||
std.utf.encode(r, dc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed ? cast(S) r : s;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1137,7 +1094,7 @@ unittest
|
||||||
S repeat(S)(S s, size_t n)
|
S repeat(S)(S s, size_t n)
|
||||||
{
|
{
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return null;
|
return S.init;
|
||||||
if (n == 1)
|
if (n == 1)
|
||||||
return s;
|
return s;
|
||||||
auto r = new Unqual!(typeof(s[0]))[n * s.length];
|
auto r = new Unqual!(typeof(s[0]))[n * s.length];
|
||||||
|
@ -1175,58 +1132,10 @@ unittest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/********************************************
|
* Alias for std.array.join
|
||||||
* Concatenate all the strings in words[] together into one
|
|
||||||
* string; use sep[] as the separator.
|
|
||||||
*/
|
*/
|
||||||
|
alias std.array.join join;
|
||||||
S join(S, S2)(in S[] words, S2 sep) if (isSomeString!S && isSomeString!S2)
|
|
||||||
{
|
|
||||||
if (!words.length) return null;
|
|
||||||
immutable seplen = sep.length;
|
|
||||||
size_t len = (words.length - 1) * seplen;
|
|
||||||
|
|
||||||
foreach (i; 0 .. words.length)
|
|
||||||
len += words[i].length;
|
|
||||||
|
|
||||||
auto result = new Unqual!(typeof(words[0][0]))[len];
|
|
||||||
|
|
||||||
size_t j;
|
|
||||||
foreach (i; 0 .. words.length)
|
|
||||||
{
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
result[j .. j + seplen] = sep;
|
|
||||||
j += seplen;
|
|
||||||
}
|
|
||||||
immutable wlen = words[i].length;
|
|
||||||
result[j .. j + wlen] = words[i];
|
|
||||||
j += wlen;
|
|
||||||
}
|
|
||||||
assert(j == len);
|
|
||||||
return cast(S) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
debug(string) printf("string.join.unittest\n");
|
|
||||||
|
|
||||||
string word1 = "peter";
|
|
||||||
string word2 = "paul";
|
|
||||||
string word3 = "jerry";
|
|
||||||
string[3] words;
|
|
||||||
string r;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
words[0] = word1;
|
|
||||||
words[1] = word2;
|
|
||||||
words[2] = word3;
|
|
||||||
r = join(words, ",");
|
|
||||||
i = cmp(r, "peter,paul,jerry");
|
|
||||||
assert(i == 0, text(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
/**************************************
|
||||||
Split $(D s[]) into an array of words, using whitespace as delimiter.
|
Split $(D s[]) into an array of words, using whitespace as delimiter.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue