Changeset 2032
- Timestamp:
- 09/18/10 21:00:52 (14 years ago)
- Files:
-
- trunk/docsrc/changelog.dd (modified) (1 diff)
- trunk/phobos/std/algorithm.d (modified) (4 diffs)
- trunk/phobos/std/array.d (modified) (3 diffs)
- trunk/phobos/std/conv.d (modified) (2 diffs)
- trunk/phobos/std/json.d (modified) (2 diffs)
- trunk/phobos/std/numeric.d (modified) (1 diff)
- trunk/phobos/std/range.d (modified) (1 diff)
- trunk/phobos/std/string.d (modified) (1 diff)
- trunk/phobos/std/xml.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/docsrc/changelog.dd
r2031 r2032 1 1 Ddoc 2 2 3 3 $(D_S D Change Log, 4 4 5 5 $(VERSION 050, Mmm dd 2010, =================================================, 6 6 7 7 8 8 $(WHATSNEW 9 9 $(LI std.traits: Most higher-order ranges now work with const/immutable arrays and other ranges 10 10 with a natural tail const, and ranges w/ const/immutable elements.) 11 $(LI Bug 4888: Heavy reliance on Bug 3534 in Phobos range usage) 11 12 $(LI std.typecons: Several improvements to the Tuple struct template: 12 13 $(UL $(LI Tuple members are now accessible with the syntax a[0], a[1] etc.) 13 14 $(LI Eliminated an internal union. See $(BUGZILLA 4421) and $(BUGZILLA 4846).) 14 15 $(LI Worked around $(BUGZILLA 4424). Got opAssign back.) 15 16 $(LI Made Tuple.slice!(from, to) to preserve field names if any.) 16 17 $(LI Added isTuple!(T) template.) 17 18 )) 18 19 ) 19 20 $(BUGSFIXED 20 21 $(LI Unlisted bug: std.exception.pointsTo() calls postblit on subobjects.) trunk/phobos/std/algorithm.d
r2009 r2032 104 104 { 105 105 return Map!(adjoin!(staticMap!(unaryFun, fun)), Range)(r); 106 106 } 107 107 else 108 108 { 109 109 return Map!(unaryFun!fun, Range)(r); 110 110 } 111 111 } 112 112 } 113 113 114 struct Map(alias fun, Range) if (isInputRange!(Range)) 115 { 114 struct Map(alias fun, Range) if (isInputRange!(Unqual!Range)) 115 { 116 alias Unqual!Range R; 116 117 alias fun _fun; 117 alias typeof({ return _fun(.ElementType!(R ange).init); }()) ElementType;118 Unqual!Range_input;118 alias typeof({ return _fun(.ElementType!(R).init); }()) ElementType; 119 R _input; 119 120 Unqual!ElementType _cache; 120 121 121 static if (isBidirectionalRange!(R ange))122 static if (isBidirectionalRange!(R)) 122 123 { 123 124 // Using a second cache would lead to at least 1 extra function evaluation 124 125 // and wasted space when 99% of the time this range will only be iterated 125 126 // over in the forward direction. Use a bool to determine whether cache 126 127 // is front or back instead. 127 128 bool cacheIsBack_; 128 129 129 130 private void fillCacheBack() 130 131 { 131 132 if (!_input.empty) _cache = _fun(_input.back); … … 145 146 { 146 147 _input.popBack; 147 148 fillCacheBack(); 148 149 } 149 150 } 150 151 151 152 private void fillCache() 152 153 { 153 154 if (!_input.empty) _cache = _fun(_input.front); 154 155 155 static if(isBidirectionalRange!(R ange))156 static if(isBidirectionalRange!(R)) 156 157 { 157 158 cacheIsBack_ = false; 158 159 } 159 160 } 160 161 161 this(R angeinput)162 this(R input) 162 163 { 163 164 _input = input; 164 165 fillCache; 165 166 } 166 167 167 static if (isInfinite!Range)168 { 169 // Propagate infinite-ness.170 enum bool empty = false;171 }168 static if (isInfinite!R) 169 { 170 // Propagate infinite-ness. 171 enum bool empty = false; 172 } 172 173 else 173 174 { 174 175 @property bool empty() 175 176 { 176 177 return _input.empty; 177 178 } 178 179 } 179 180 180 181 void popFront() 181 182 { 182 183 _input.popFront; 183 184 fillCache(); 184 185 } 185 186 186 187 @property ElementType front() 187 188 { 188 static if (isBidirectionalRange!(R ange))189 static if (isBidirectionalRange!(R)) 189 190 { 190 191 if (cacheIsBack_) 191 192 { 192 193 fillCache(); 193 194 } 194 195 } 195 196 return _cache; 196 197 } 197 198 198 static if (isRandomAccessRange!R ange)199 static if (isRandomAccessRange!R) 199 200 { 200 201 ElementType opIndex(size_t index) 201 202 { 202 203 return _fun(_input[index]); 203 204 } 204 205 } 205 206 206 207 // hasLength is busted, Bug 2873 207 208 static if (is(typeof(_input.length) : size_t) 208 209 || is(typeof(_input.length()) : size_t)) 209 210 { 210 211 @property size_t length() 211 212 { 212 213 return _input.length; 213 214 } 214 215 } 215 216 216 static if (hasSlicing!(R ange))217 static if (hasSlicing!(R)) 217 218 { 218 219 typeof(this) opSlice(size_t lowerBound, size_t upperBound) 219 220 { 220 221 return typeof(this)(_input[lowerBound..upperBound]); 221 222 } 222 223 } 223 224 224 static if (isForwardRange!Range)225 @property Map save()226 {227 auto result = this;228 result._input = result._input.save;229 return result;230 }225 static if (isForwardRange!R) 226 @property Map save() 227 { 228 auto result = this; 229 result._input = result._input.save; 230 return result; 231 } 231 232 } 232 233 233 234 unittest 234 235 { 235 236 debug(std_algorithm) scope(success) 236 237 writeln("unittest @", __FILE__, ":", __LINE__, " done."); 237 238 alias map!(to!string) stringize; 238 239 assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ])); 239 240 uint counter; 240 241 alias map!((a) { return counter++; }) count; … … 843 844 version (all) 844 845 { 845 846 /* This is the older version. Too many problems with the newer one. 846 847 */ 847 848 Filter!(unaryFun!(pred), Range) 848 849 filter(alias pred, Range)(Range rs) 849 850 { 850 851 return typeof(return)(rs); 851 852 } 852 853 853 struct Filter(alias pred, Range) if (isInputRange!(Range)) 854 { 855 Unqual!Range _input; 856 857 this(Range r) 854 struct Filter(alias pred, Range) if (isInputRange!(Unqual!Range)) 855 { 856 alias Unqual!Range R; 857 R _input; 858 859 this(R r) 858 860 { 859 861 _input = r; 860 862 while (!_input.empty && !pred(_input.front)) _input.popFront; 861 863 } 862 864 863 865 ref Filter opSlice() 864 866 { 865 867 return this; 866 868 } 867 869 … … 872 874 { 873 875 _input.popFront; 874 876 } while (!_input.empty && !pred(_input.front)); 875 877 } 876 878 877 879 ElementType!(Range) front() 878 880 { 879 881 return _input.front; 880 882 } 881 883 882 static if(isForwardRange!R ange)884 static if(isForwardRange!R) 883 885 { 884 886 @property typeof(this) save() 885 887 { 886 888 return typeof(this)(_input); 887 889 } 888 890 } 889 891 } 890 892 891 893 unittest 892 894 { trunk/phobos/std/array.d
r2005 r2032 246 246 assert(b is a); 247 247 } 248 248 ---- 249 249 */ 250 250 251 251 @property T[] save(T)(T[] a) 252 252 { 253 253 return a; 254 254 } 255 255 256 private template notConst(T) { 257 enum notConst = !is(T == const) && !is(T == immutable); 258 } 259 256 260 /** 257 261 Implements the range interface primitive $(D popFront) for built-in 258 262 arrays. Due to the fact that nonmember functions can be called with 259 263 the first argument using the dot notation, $(D array.popFront) is 260 264 equivalent to $(D popFront(array)). 261 265 262 266 263 267 Example: 264 268 ---- 265 269 void main() 266 270 { 267 271 int[] a = [ 1, 2, 3 ]; 268 272 a.popFront; 269 273 assert(a == [ 2, 3 ]); 270 274 } 271 275 ---- 272 276 */ 273 277 274 void popFront(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar)) 275 { 278 void popFront(A)(ref A a) 279 if(!isNarrowString!A && isDynamicArray!A && notConst!A) 280 { 281 alias typeof(A[0]) T; 276 282 assert(a.length, "Attempting to popFront() past the end of an array of " 277 283 ~ T.stringof); 278 284 a = a[1 .. $]; 279 285 } 280 286 281 287 unittest 282 288 { 283 289 //@@@BUG 2608@@@ 284 290 //auto a = [ 1, 2, 3 ]; 285 291 int[] a = [ 1, 2, 3 ]; 286 292 a.popFront; 287 293 assert(a == [ 2, 3 ]); 288 } 289 290 void popFront(T)(ref T[] a) if (is(Unqual!T == char) || is(Unqual!T == wchar)) 291 { 294 295 static assert(!__traits(compiles, popFront!(immutable int[]))); 296 } 297 298 void popFront(A)(ref A a) 299 if(isNarrowString!A && notConst!A) 300 { 301 alias typeof(a[0]) T; 292 302 assert(a.length, "Attempting to popFront() past the end of an array of " 293 303 ~ T.stringof); 294 304 a = a[std.utf.stride(a, 0) .. $]; 295 305 } 296 306 297 307 unittest 298 308 { 299 309 string s1 = "\xC2\xA9hello"; 300 310 s1.popFront(); 301 311 assert(s1 == "hello"); 302 312 wstring s2 = "\xC2\xA9hello"; 303 313 s2.popFront(); 304 314 assert(s2 == "hello"); 305 315 string s3 = "\u20AC100"; 306 316 //write(s3, '\n'); 317 318 static assert(!__traits(compiles, popFront!(immutable string))); 307 319 } 308 320 309 321 /** 310 322 Implements the range interface primitive $(D popBack) for built-in 311 323 arrays. Due to the fact that nonmember functions can be called with 312 324 the first argument using the dot notation, $(D array.popBack) is 313 325 equivalent to $(D popBack(array)). 314 326 315 327 316 328 Example: 317 329 ---- 318 330 void main() 319 331 { 320 332 int[] a = [ 1, 2, 3 ]; 321 333 a.popBack; 322 334 assert(a == [ 1, 2 ]); 323 335 } 324 336 ---- 325 337 */ 326 338 327 void popBack(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar)) 339 void popBack(A)(ref A a) 340 if(isDynamicArray!A && !isNarrowString!A && notConst!A) 328 341 { 329 342 assert(a.length); 330 343 a = a[0 .. $ - 1]; 331 344 } 332 345 333 346 unittest 334 347 { 335 348 //@@@BUG 2608@@@ 336 349 //auto a = [ 1, 2, 3 ]; 337 350 int[] a = [ 1, 2, 3 ]; 338 351 a.popBack; 339 352 assert(a == [ 1, 2 ]); 340 } 341 342 void popBack(T)(ref T[] a) if (is(Unqual!T == char)) 353 354 static assert(!__traits(compiles, popBack!(immutable int[]))); 355 } 356 357 void popBack(A)(ref A a) 358 if(is(A : const(char)[]) && notConst!A) 343 359 { 344 360 immutable n = a.length; 345 361 const p = a.ptr + n; 346 362 if (n >= 1 && (p[-1] & 0b1100_0000) != 0b1000_0000) 347 363 { 348 364 a = a[0 .. n - 1]; 349 365 } 350 366 else if (n >= 2 && (p[-2] & 0b1100_0000) != 0b1000_0000) 351 367 { 352 368 a = a[0 .. n - 2]; … … 369 385 { 370 386 string s = "hello\xE2\x89\xA0"; 371 387 s.popBack(); 372 388 assert(s == "hello", s); 373 389 374 390 string s3 = "\xE2\x89\xA0"; 375 391 auto c = s3.back; 376 392 assert(c == cast(dchar)'\u2260'); 377 393 s3.popBack(); 378 394 assert(s3 == ""); 379 } 380 381 void popBack(T)(ref T[] a) if (is(Unqual!T == wchar)) 395 396 static assert(!__traits(compiles, popBack!(immutable char[]))); 397 } 398 399 void popBack(A)(ref A a) 400 if(is(A : const(wchar)[]) && notConst!A) 382 401 { 383 402 assert(a.length); 384 403 if (a.length == 1) 385 404 { 386 405 a = a[0 .. 0]; 387 406 return; 388 407 } 389 408 immutable c = a[$ - 2]; 390 409 a = a[0 .. $ - 1 - (c >= 0xD800 && c <= 0xDBFF)]; 391 410 } 392 411 393 412 unittest 394 413 { 395 414 wstring s = "hello\xE2\x89\xA0"; 396 415 s.popBack(); 397 416 assert(s == "hello"); 417 418 static assert(!__traits(compiles, popBack!(immutable wchar[]))); 398 419 } 399 420 400 421 /** 401 422 Implements the range interface primitive $(D front) for built-in 402 423 arrays. Due to the fact that nonmember functions can be called with 403 424 the first argument using the dot notation, $(D array.front) is 404 425 equivalent to $(D front(array)). 405 426 406 427 407 428 Example: … … 830 851 private static size_t newCapacity(size_t newlength) 831 852 { 832 853 long mult = 100 + (1000L) / (bsr(newlength * T.sizeof) + 1); 833 854 // limit to doubling the length, we don't want to grow too much 834 855 if(mult > 200) 835 856 mult = 200; 836 857 auto newext = cast(size_t)((newlength * mult + 99) / 100); 837 858 return newext > newlength ? newext : newlength; 838 859 } 839 860 861 // Const fixing hack. 862 void put(Range)(Range items) 863 if(isInputRange!(Unqual!Range) && !isInputRange!Range) { 864 alias put!(Unqual!Range) p; 865 p(items); 866 } 867 840 868 /** 841 869 Appends an entire range to the managed array. 842 870 */ 843 871 void put(Range)(Range items) if (isInputRange!Range 844 872 && is(typeof(Appender.init.put(items.front)))) 845 873 { 846 874 // note, we disable this branch for appending one type of char to 847 875 // another because we can't trust the length portion. 848 876 static if (!(isSomeChar!T && isSomeChar!(ElementType!Range) && 849 877 !is(Range == Unqual!(T)[])) && trunk/phobos/std/conv.d
r2021 r2032 101 101 combination of qualifiers (mutable, $(D const), or $(D immutable)). 102 102 103 103 Example: 104 104 ---- 105 105 char[] a = "abc"; 106 106 auto b = to!dstring(a); 107 107 assert(b == "abc"w); 108 108 ---- 109 109 */ 110 110 T toImpl(T, S)(S s) if (!implicitlyConverts!(S, T) && isSomeString!T 111 && isInputRange! S&& isSomeChar!(ElementType!S))111 && isInputRange!(Unqual!S) && isSomeChar!(ElementType!S)) 112 112 { 113 113 static if (isSomeString!S) 114 114 { 115 115 // string-to-string conversion 116 116 static if (s[0].sizeof == T[0].sizeof) { 117 117 // same width, only qualifier conversion 118 118 enum tIsConst = is(T == const(char)[]) || is(T == const(wchar)[]) 119 119 || is(T == const(dchar)[]); 120 120 enum tIsInvariant = is(T == immutable(char)[]) 121 121 || is(T == immutable(wchar)[]) || is(T == immutable(dchar)[]); … … 175 175 } 176 176 } 177 177 178 178 /** 179 179 Converts array (other than strings) to string. The left bracket, 180 180 separator, and right bracket are configurable. Each element is 181 181 converted by calling $(D to!T). 182 182 */ 183 183 T toImpl(T, S)(S s, in T leftBracket = "[", in T separator = " ", 184 184 in T rightBracket = "]") 185 if (isSomeString!T && !isSomeChar!(ElementType!S) && isInputRange!S) 186 { 187 alias Unqual!(typeof(T.init[0])) Char; 188 // array-to-string conversion 189 auto result = appender!(Char[])(); 190 result.put(leftBracket); 191 bool first = true; 192 for (; !s.empty; s.popFront()) 193 { 194 if (!first) 195 { 196 result.put(separator); 197 } 198 else 199 { 200 first = false; 201 } 202 result.put(to!T(s.front)); 203 } 204 result.put(rightBracket); 205 return cast(T) result.data; 185 if (isSomeString!T && !isSomeChar!(ElementType!S) && 186 (isInputRange!S || isInputRange!(Unqual!S))) 187 { 188 static if(!isInputRange!S) { 189 alias toImpl!(T, Unqual!S) ti; 190 return ti(s, leftBracket, separator, rightBracket); 191 } else { 192 alias Unqual!(typeof(T.init[0])) Char; 193 // array-to-string conversion 194 auto result = appender!(Char[])(); 195 result.put(leftBracket); 196 bool first = true; 197 for (; !s.empty; s.popFront()) 198 { 199 if (!first) 200 { 201 result.put(separator); 202 } 203 else 204 { 205 first = false; 206 } 207 result.put(to!T(s.front)); 208 } 209 result.put(rightBracket); 210 return cast(T) result.data; 211 } 206 212 } 207 213 208 214 /* 209 215 Converting static arrays forwards to their dynamic counterparts. 210 216 */ 211 217 T toImpl(T, S)(ref S s) 212 218 if (isStaticArray!S) 213 219 { 214 220 return toImpl!(T, typeof(s[0])[])(s); 215 221 } trunk/phobos/std/json.d
r1925 r2032 50 50 real floating; 51 51 JSONValue[string] object; 52 52 JSONValue[] array; 53 53 } 54 54 JSON_TYPE type; 55 55 } 56 56 57 57 /** 58 58 Parses a serialized string and returns a tree of JSON values. 59 59 */ 60 JSONValue parseJSON(T)( inT json, int maxDepth = -1) if(isInputRange!T) {60 JSONValue parseJSON(T)(T json, int maxDepth = -1) if(isInputRange!T) { 61 61 JSONValue root = void; 62 62 root.type = JSON_TYPE.NULL; 63 63 64 64 if(json.empty()) return root; 65 65 66 66 int depth = -1; 67 67 dchar next = 0; 68 68 int line = 1, pos = 1; 69 69 70 70 void error(string msg) { … … 420 420 } 421 421 } 422 422 423 423 version(unittest) import std.stdio; 424 424 425 425 unittest { 426 426 // An overly simple test suite, if it can parse a serializated string and 427 427 // then use the resulting values tree to generate an identical 428 428 // serialization, both the decoder and encoder works. 429 429 430 immutablejsons = [430 auto jsons = [ 431 431 `null`, 432 432 `true`, 433 433 `false`, 434 434 `0`, 435 435 `123`, 436 436 `-4321`, 437 437 `0.23`, 438 438 `-0.23`, 439 439 `""`, 440 440 `1.223e+24`, trunk/phobos/std/numeric.d
r1953 r2032 2460 2460 2461 2461 /// ditto 2462 2462 void inverseFft(Ret, R)(R range, Ret buf) { 2463 2463 mixin(MakeLocalFft); 2464 2464 return fftObj.inverseFft!(Ret, R)(range, buf); 2465 2465 } 2466 2466 2467 2467 2468 2468 unittest { 2469 2469 // Test values from R. 2470 constarr = [1,2,3,4,5,6,7,8];2471 constfft1 = fft(arr);2470 auto arr = [1,2,3,4,5,6,7,8]; 2471 auto fft1 = fft(arr); 2472 2472 assert(approxEqual(map!"a.re"(fft1), 2473 2473 [36.0, -4, -4, -4, -4, -4, -4, -4])); 2474 2474 assert(approxEqual(map!"a.im"(fft1), 2475 2475 [0, 9.6568, 4, 1.6568, 0, -1.6568, -4, -9.6568])); 2476 2476 2477 2477 alias Complex!float C; 2478 constarr2 = [C(1,2), C(3,4), C(5,6), C(7,8), C(9,10),2478 auto arr2 = [C(1,2), C(3,4), C(5,6), C(7,8), C(9,10), 2479 2479 C(11,12), C(13,14), C(15,16)]; 2480 constfft2 = fft(arr2);2480 auto fft2 = fft(arr2); 2481 2481 assert(approxEqual(map!"a.re"(fft2), 2482 2482 [64.0, -27.3137, -16, -11.3137, -8, -4.6862, 0, 11.3137])); 2483 2483 assert(approxEqual(map!"a.im"(fft2), 2484 2484 [72, 11.3137, 0, -4.686, -8, -11.3137, -16, -27.3137])); 2485 2485 2486 constinv1 = inverseFft(fft1);2486 auto inv1 = inverseFft(fft1); 2487 2487 assert(approxEqual(map!"a.re"(inv1), arr)); 2488 2488 assert(reduce!max(map!"a.im"(inv1)) < 1e-10); 2489 2489 2490 constinv2 = inverseFft(fft2);2490 auto inv2 = inverseFft(fft2); 2491 2491 assert(approxEqual(map!"a.re"(inv2), map!"a.re"(arr2))); 2492 2492 assert(approxEqual(map!"a.im"(inv2), map!"a.im"(arr2))); 2493 2493 2494 2494 // FFTs of size 0, 1 and 2 are handled as special cases. Test them here. 2495 constushort[] empty;2495 ushort[] empty; 2496 2496 assert(fft(empty) == null); 2497 2497 assert(inverseFft(fft(empty)) == null); 2498 2498 2499 constreal[] oneElem = [4.5L];2500 constoneFft = fft(oneElem);2499 real[] oneElem = [4.5L]; 2500 auto oneFft = fft(oneElem); 2501 2501 assert(oneFft.length == 1); 2502 2502 assert(oneFft[0].re == 4.5L); 2503 2503 assert(oneFft[0].im == 0); 2504 2504 2505 constoneInv = inverseFft(oneFft);2505 auto oneInv = inverseFft(oneFft); 2506 2506 assert(oneInv.length == 1); 2507 2507 assert(approxEqual(oneInv[0].re, 4.5)); 2508 2508 assert(approxEqual(oneInv[0].im, 0)); 2509 2509 2510 immutablelong[2] twoElems = [8, 4];2511 consttwoFft = fft(twoElems[]);2510 long[2] twoElems = [8, 4]; 2511 auto twoFft = fft(twoElems[]); 2512 2512 assert(twoFft.length == 2); 2513 2513 assert(approxEqual(twoFft[0].re, 12)); 2514 2514 assert(approxEqual(twoFft[0].im, 0)); 2515 2515 assert(approxEqual(twoFft[1].re, 4)); 2516 2516 assert(approxEqual(twoFft[1].im, 0)); 2517 consttwoInv = inverseFft(twoFft);2517 auto twoInv = inverseFft(twoFft); 2518 2518 assert(approxEqual(twoInv[0].re, 8)); 2519 2519 assert(approxEqual(twoInv[0].im, 0)); 2520 2520 assert(approxEqual(twoInv[1].re, 4)); 2521 2521 assert(approxEqual(twoInv[1].im, 0)); 2522 2522 } 2523 2523 2524 2524 // Swaps the real and imaginary parts of a complex number. This is useful 2525 2525 // for inverse FFTs. 2526 2526 C swapRealImag(C)(C input) { 2527 2527 return C(input.im, input.re); trunk/phobos/std/range.d
r2021 r2032 3295 3295 /// Ditto 3296 3296 Lockstep!(Ranges) lockstep(Ranges...)(Ranges ranges, StoppingPolicy s) 3297 3297 { 3298 3298 assert(0); 3299 3299 } 3300 3300 } 3301 3301 else 3302 3302 { 3303 3303 // Work around DMD bugs 4676, 4652. 3304 3304 auto lockstep(Args...)(Args args) 3305 if(allSatisfy!(isInputRange, Args) || (3306 allSatisfy!(isInputRange, Args[0..$ - 1]) &&3305 if(allSatisfy!(isInputRange, staticMap!(Unqual, Args)) || ( 3306 allSatisfy!(isInputRange, staticMap!(Unqual, Args[0..$ - 1])) && 3307 3307 is(Args[$ - 1] == StoppingPolicy)) 3308 3308 ) 3309 3309 { 3310 3310 static if(is(Args[$ - 1] == StoppingPolicy)) 3311 3311 { 3312 3312 alias args[0..$ - 1] ranges; 3313 3313 alias Args[0..$ - 1] Ranges; 3314 3314 alias args[$ - 1] stoppingPolicy; 3315 3315 } 3316 3316 else trunk/phobos/std/string.d
r1993 r2032 534 534 535 535 $(D CaseSensitive cs) controls whether the comparisons are case 536 536 sensitive or not. 537 537 538 538 Returns: 539 539 540 540 Index in $(D s) where $(D sub) is found, $(D -1) if not found. 541 541 */ 542 542 543 543 sizediff_t 544 indexOf(Char1, Char2)( in Char1[] s, in Char2[] sub,544 indexOf(Char1, Char2)(const(Char1)[] s, const(Char2)[] sub, 545 545 CaseSensitive cs = CaseSensitive.yes) 546 546 { 547 547 if (cs == CaseSensitive.yes) 548 548 { 549 549 static if (Char1.sizeof == Char2.sizeof) 550 550 { 551 551 immutable result = s.length - std.algorithm.find(s, sub).length; 552 552 return result == s.length ? -1 : result; 553 553 } 554 554 else trunk/phobos/std/xml.d
r1934 r2032 118 118 Distributed under the Boost Software License, Version 1.0. 119 119 (See accompanying file LICENSE_1_0.txt or copy at 120 120 http://www.boost.org/LICENSE_1_0.txt) 121 121 */ 122 122 module std.xml; 123 123 124 124 import std.array; 125 125 import std.string; 126 126 import std.encoding; 127 127 128 immutablecdata = "<