Changeset 1898
- Timestamp:
- 08/19/10 00:53:05 (14 years ago)
- Files:
-
- trunk/docsrc/changelog.dd (modified) (1 diff)
- trunk/phobos/std/array.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/docsrc/changelog.dd
r1897 r1898 27 27 $(LI $(BUGZILLA 3312): std.string.count should use const(char)[], not immutable.) 28 28 $(LI $(BUGZILLA 3348): Documentation for many std.process functions has disappeared) 29 29 $(LI $(BUGZILLA 3361): code in std.zlib concatenates void[] arrays ) 30 30 $(LI $(BUGZILLA 3877): std.range.chain do not manage infinite ranges correctly) 31 31 $(LI $(BUGZILLA 3894): std.range.Stride!R requires R.front() and R.back() to return by reference) 32 32 $(LI $(BUGZILLA 3946): schwartzSort - SwapStrategy always unstable) 33 33 $(LI $(BUGZILLA 4402): std.range.Zip doesn't work w/ non-lvalue ranges.) 34 34 $(LI $(BUGZILLA 4408): Ambiguity when using std.algorithm.splitter with generic ranges.) 35 35 $(LI $(BUGZILLA 4292): CommonType fails for singular alias value.) 36 36 $(LI $(BUGZILLA 4345): std.range.take!string: "Nonsensical finite range with slicing but no length".) 37 $(LI $(BUGZILLA 4345): More flexible std.array.array.) 37 38 $(LI $(BUGZILLA 4363): Some phobos ranges are not forward ranges (but should be).) 38 39 $(LI $(BUGZILLA 4381): Length attribute for std.typecons.Tuple.) 39 40 $(LI $(BUGZILLA 4387): std.range.Cycle assumes lvalue elements.) 40 41 $(LI $(BUGZILLA 4388): std.range.Radial assumes lvalue elements.) 41 42 $(LI $(BUGZILLA 4403): std.range.FrontTransversal assumes lvalue elements.) 42 43 $(LI $(BUGZILLA 4404): std.range.Transversal assumes lvalue elements.) 43 44 $(LI $(BUGZILLA 4455): Taking the sqrt of an integer shouldn't require an explicit cast.) 44 45 $(LI $(BUGZILLA 4464): std.range.take does not always return Take!R.) 45 46 ) 46 47 ) trunk/phobos/std/array.d
r1813 r1898 12 12 */ 13 13 module std.array; 14 14 15 15 import std.c.stdio; 16 16 import core.memory; 17 17 import std.algorithm, std.conv, std.encoding, std.exception, std.range, 18 18 std.string, std.traits, std.typecons, std.utf; 19 19 version(unittest) private import std.stdio; 20 20 21 21 /** 22 Returns a newly-allocated array consisting of a copy of the input 23 range $(D r). 22 Returns a newly-allocated dynamic array consisting of a copy of the input 23 range, static array, dynamic array, or class or struct with an $(D opApply) 24 function $(D r). Note that narrow strings are handled 25 as a special case in an overload. 24 26 25 27 Example: 26 28 27 29 ---- 28 30 auto a = array([1, 2, 3, 4, 5][]); 29 31 assert(a == [ 1, 2, 3, 4, 5 ]); 30 32 ---- 31 33 */ 32 ElementType!Range[] array(Range)(Range r) if (isInputRange!Range) 33 { 34 alias ElementType!Range E; 34 ForeachType!Range[] array(Range)(Range r) 35 if (isIterable!Range && !isNarrowString!Range) 36 { 37 alias ForeachType!Range E; 35 38 static if (hasLength!Range) 36 39 { 37 40 if (r.empty) return null; 38 41 39 42 // Determines whether the GC should scan the array. 40 43 auto blkInfo = (typeid(E).flags & 1) ? 41 44 cast(GC.BlkAttr) 0 : 42 45 GC.BlkAttr.NO_SCAN; 43 46 44 47 auto result = (cast(E*) enforce(GC.malloc(r.length * E.sizeof, blkInfo), 45 48 text("Out of memory while allocating an array of ", r.length, 46 49 " objects of type ", E.stringof)))[0 .. r.length]; 47 foreach (ref e; result) 50 size_t i = 0; 51 foreach (e; r) 48 52 { 49 53 // hacky 50 static if (is(typeof( &e.opAssign)))54 static if (is(typeof(e.opAssign(e)))) 51 55 { 52 56 // this should be in-place construction 53 new(&e) E(r.front); 57 auto voidArr = (cast(void*) (result.ptr + i))[0..E.sizeof]; 58 emplace!E(voidArr, e); 54 59 } 55 60 else 56 61 { 57 e = r.front;62 result[i] = e; 58 63 } 59 r.popFront;64 i++; 60 65 } 61 66 return result; 62 67 } 63 68 else 64 69 { 65 70 auto a = appender!(E[])(); 66 71 foreach (e; r) 67 72 { 68 73 a.put(e); 69 74 } … … 97 102 // { 98 103 // result[constructedElements] = src; 99 104 // } 100 105 // ++constructedElements; 101 106 // } 102 107 // // 3. Success constructing all elements, type the array and return it 103 108 // setTypeInfo(typeid(E), result); 104 109 // return result[0 .. constructedElements]; 105 110 } 106 111 112 /** 113 Convert a narrow string to an array type that fully supports random access. 114 This is handled as a special case and always returns a $(D dchar[]), 115 $(D const(dchar)[]), or $(D immutable(dchar)[]) depending on the constness of 116 the input. 117 */ 118 ElementType!String[] array(String)(String str) if(isNarrowString!String) 119 { 120 static if(is(typeof(return) == immutable)) 121 { 122 return to!(immutable(dchar)[])(str); 123 } 124 else static if(is(typeof(return) == const)) 125 { 126 return to!(const(dchar)[])(str); 127 } 128 else 129 { 130 return to!(dchar[])(str); 131 } 132 } 133 107 134 version(unittest) 108 135 { 109 136 struct TestArray { int x; string toString() { return .to!string(x); } } 137 138 struct OpAssign 139 { 140 uint num; 141 this(uint num) { this.num = num; } 142 143 // Templating opAssign to make sure the bugs with opAssign being 144 // templated are fixed. 145 void opAssign(T)(T rhs) { this.num = rhs.num; } 146 } 147 148 struct OpApply 149 { 150 int opApply(int delegate(ref int) dg) 151 { 152 int res; 153 foreach(i; 0..10) 154 { 155 res = dg(i); 156 if(res) break; 157 } 158 159 return res; 160 } 161 } 110 162 } 111 163 112 164 unittest 113 165 { 114 166 auto a = array([1, 2, 3, 4, 5][]); 115 167 //writeln(a); 116 168 assert(a == [ 1, 2, 3, 4, 5 ]); 117 169 118 170 auto b = array([TestArray(1), TestArray(2)][]); 119 171 //writeln(b); … … 123 175 int x; 124 176 this(int y) { x = y; } 125 177 override string toString() { return .to!string(x); } 126 178 } 127 179 auto c = array([new C(1), new C(2)][]); 128 180 //writeln(c); 129 181 130 182 auto d = array([1., 2.2, 3][]); 131 183 assert(is(typeof(d) == double[])); 132 184 //writeln(d); 185 186 auto e = [OpAssign(1), OpAssign(2)]; 187 auto f = array(e); 188 assert(e == f); 189 190 assert(array(OpApply.init) == [0,1,2,3,4,5,6,7,8,9]); 191 assert(array("ABC") == "ABC"d); 192 assert(array("ABC".dup) == "ABC"d.dup); 133 193 } 134 194 135 195 template IndexType(C : T[], T) 136 196 { 137 197 alias size_t IndexType; 138 198 } 139 199 140 200 unittest 141 201 { 142 202 static assert(is(IndexType!(double[]) == size_t));
