Changeset 1703
- Timestamp:
- 07/01/10 02:39:50 (14 years ago)
- Files:
-
- trunk/phobos/std/algorithm.d (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/std/algorithm.d
r1702 r1703 570 570 } 571 571 572 572 } 573 573 574 574 ref Filter opSlice() 575 575 { 576 576 return this; 577 577 } 578 578 579 579 static if(isInfinite!Range) { 580 enum bool empty = false; 580 enum bool empty = false; // Propagate infiniteness. 581 581 } else { 582 582 bool empty() { return _input.empty; } 583 583 } 584 584 585 585 void popFront() 586 586 { 587 587 do 588 588 { 589 589 _input.popFront; 590 590 } while (!_input.empty && !pred(_input.front)); … … 867 867 868 868 public: 869 869 this(Range input, Separator separator) 870 870 { 871 871 _input = input; 872 872 _separator = separator; 873 873 // computeFront(); 874 874 // computeBack(); 875 875 } 876 876 877 @property bool empty() 878 { 879 return _frontLength == _atEnd; 877 static if(isInfinite!Range) 878 { 879 enum bool empty = false; 880 } else 881 { 882 @property bool empty() 883 { 884 return _frontLength == _atEnd; 885 } 880 886 } 881 887 882 888 @property Range front() 883 889 { 884 890 assert(!empty); 885 891 if (_frontLength == _unComputed) 886 892 { 887 893 _frontLength = _input.indexOf(_separator); 888 894 if (_frontLength == -1) _frontLength = _input.length; 889 895 } … … 989 995 } 990 996 } 991 997 992 998 public: 993 999 this(Range input, Separator separator) 994 1000 { 995 1001 _input = input; 996 1002 _separator = separator; 997 1003 } 998 1004 999 Range front()1005 @property Range front() 1000 1006 { 1001 1007 assert(!empty); 1002 1008 ensureFrontLength; 1003 1009 return _input[0 .. _frontLength]; 1004 1010 } 1005 1011 1006 bool empty() 1007 { 1008 return _frontLength == size_t.max && _input.empty; 1012 static if(isInfinite!Range) 1013 { 1014 enum bool empty = false; // Propagate infiniteness 1015 } 1016 else 1017 { 1018 @property bool empty() 1019 { 1020 return _frontLength == size_t.max && _input.empty; 1021 } 1009 1022 } 1010 1023 1011 1024 void popFront() 1012 1025 { 1013 1026 assert(!empty); 1014 1027 ensureFrontLength; 1015 1028 if (_frontLength == _input.length) 1016 1029 { 1017 1030 // done, there's no separator in sight 1018 1031 _input = _input[_frontLength .. _frontLength]; … … 1034 1047 // Normal case, pop one item and the separator, get ready for 1035 1048 // reading the next item 1036 1049 _input = _input[_frontLength + separatorLength .. _input.length]; 1037 1050 // mark _frontLength as uninitialized 1038 1051 _frontLength = _frontLength.max; 1039 1052 } 1040 1053 1041 1054 // Bidirectional functionality as suggested by Brad Roberts. 1042 1055 static if (isBidirectionalRange!Range) 1043 1056 { 1044 Range back()1057 @property Range back() 1045 1058 { 1046 1059 ensureBackLength; 1047 1060 return _input[_input.length - _backLength .. _input.length]; 1048 1061 } 1049 1062 1050 1063 void popBack() 1051 1064 { 1052 1065 ensureBackLength; 1053 1066 if (_backLength == _input.length) 1054 1067 { … … 1136 1149 else 1137 1150 { 1138 1151 // Chase first terminator 1139 1152 while (_end < _input.length && !_isTerminator(_input[_end])) 1140 1153 { 1141 1154 ++_end; 1142 1155 } 1143 1156 } 1144 1157 } 1145 1158 1146 @property bool empty() 1147 { 1148 return _end == _end.max; 1159 static if(isInfinite!Range) 1160 { 1161 enum bool empty = false; // Propagate infiniteness. 1162 } 1163 else 1164 { 1165 @property bool empty() 1166 { 1167 return _end == _end.max; 1168 } 1149 1169 } 1150 1170 1151 1171 @property Range front() 1152 1172 { 1153 1173 assert(!empty); 1154 1174 return _input[0 .. _end]; 1155 1175 } 1156 1176 1157 1177 void popFront() 1158 1178 { … … 1250 1270 void popFront() 1251 1271 { 1252 1272 auto last = _input.front; 1253 1273 do 1254 1274 { 1255 1275 _input.popFront; 1256 1276 } 1257 1277 while (!_input.empty && binaryFun!(pred)(last, _input.front)); 1258 1278 } 1259 1279 1260 static if(isBidirectionalRange!R) { 1280 @property ElementType!(R) front() { return _input.front; } 1281 1282 static if(isBidirectionalRange!R) 1283 { 1261 1284 void popBack() 1262 1285 { 1263 1286 auto last = _input.back; 1264 1287 do 1265 1288 { 1266 1289 _input.popBack; 1267 1290 } 1268 1291 while (!_input.empty && binaryFun!(pred)(last, _input.back)); 1269 1292 } 1270 1293 1271 ElementType!(R) back() { return _input.back; } 1272 } 1273 1274 bool empty() { return _input.empty; } 1275 ElementType!(R) front() { return _input.front; } 1294 @property ElementType!(R) back() { return _input.back; } 1295 } 1296 1297 static if(isInfinite!R) 1298 { 1299 enum bool empty = false; // Propagate infiniteness. 1300 } 1301 else 1302 { 1303 @property bool empty() { return _input.empty; } 1304 } 1305 1276 1306 1277 1307 static if(isForwardRange!R) { 1278 1308 @property typeof(this) save() { 1279 1309 return typeof(this)(_input.save); 1280 1310 } 1281 1311 } 1282 1312 } 1283 1313 1284 1314 /// Ditto 1285 1315 Uniq!(pred, Range) uniq(alias pred = "a == b", Range)(Range r) … … 1348 1378 _current = tuple(_input.front, 1u); 1349 1379 _input.popFront; 1350 1380 while (!_input.empty && comp(_current.field[0], _input.front)) 1351 1381 { 1352 1382 ++_current.field[1]; 1353 1383 _input.popFront; 1354 1384 } 1355 1385 } 1356 1386 } 1357 1387 1358 @property bool empty() 1359 { 1360 return _current.field[1] == 0; 1388 static if(isInfinite!R) 1389 { 1390 enum bool empty = false; // Propagate infiniteness. 1391 } 1392 else 1393 { 1394 @property bool empty() 1395 { 1396 return _current.field[1] == 0; 1397 } 1361 1398 } 1362 1399 1363 1400 @property ref Tuple!(ElementType!R, uint) front() 1364 1401 { 1365 1402 assert(!empty); 1366 1403 return _current; 1367 1404 } 1368 1405 1369 1406 static if(isForwardRange!R) { 1370 1407 @property typeof(this) save() { … … 2031 2068 _done = _input.empty || openRight && predSatisfied(); 2032 2069 } 2033 2070 else 2034 2071 this(Range input, OpenRight openRight = OpenRight.yes) 2035 2072 { 2036 2073 _input = input; 2037 2074 _openRight = openRight; 2038 2075 _done = _input.empty || openRight && predSatisfied(); 2039 2076 } 2040 2077 2041 bool empty()2078 @property bool empty() 2042 2079 { 2043 2080 return _done; 2044 2081 } 2045 2082 2046 ElementType!Range front()2083 @property ElementType!Range front() 2047 2084 { 2048 2085 assert(!empty); 2049 2086 return _input.front; 2050 2087 } 2051 2088 2052 2089 bool predSatisfied() 2053 2090 { 2054 2091 static if (is(Sentinel == void)) 2055 2092 return unaryFun!pred(_input.front); 2056 2093 else … … 5467 5504 5468 5505 public: 5469 5506 alias CommonType!(staticMap!(.ElementType, Rs)) ElementType; 5470 5507 5471 5508 this(Rs rs) 5472 5509 { 5473 5510 this._r = rs; 5474 5511 adjustPosition(); 5475 5512 } 5476 5513 5477 bool empty()5514 @property bool empty() 5478 5515 { 5479 5516 return _crt == _crt.max; 5480 5517 } 5481 5518 5482 5519 void popFront() 5483 5520 { 5484 5521 // Assumes _crt is correct 5485 5522 assert(!empty); 5486 5523 foreach (i, U; Rs) 5487 5524 { 5488 5525 if (i < _crt) continue; 5489 5526 // found _crt 5490 5527 assert(!_r[i].empty); 5491 5528 _r[i].popFront; 5492 5529 adjustPosition(); 5493 5530 return; 5494 5531 } 5495 5532 assert(false); 5496 5533 } 5497 5534 5498 ElementType front()5535 @property ElementType front() 5499 5536 { 5500 5537 assert(!empty); 5501 5538 // Assume _crt is correct 5502 5539 foreach (i, U; Rs) 5503 5540 { 5504 5541 if (i < _crt) continue; 5505 5542 assert(!_r[i].empty); 5506 5543 return _r[i].front; 5507 5544 } 5508 5545 assert(false); … … 5586 5623 } 5587 5624 5588 5625 public: 5589 5626 this(Rs input) 5590 5627 { 5591 5628 this._input = input; 5592 5629 // position to the first element 5593 5630 adjustPosition; 5594 5631 } 5595 5632 5596 bool empty()5633 @property bool empty() 5597 5634 { 5598 5635 foreach (i, U; Rs) 5599 5636 { 5600 5637 if (_input[i].empty) return true; 5601 5638 } 5602 5639 return false; 5603 5640 } 5604 5641 5605 5642 void popFront() 5606 5643 { 5607 5644 assert(!empty); 5608 5645 assert(!comp(_input[0].front, _input[1].front) 5609 5646 && !comp(_input[1].front, _input[0].front)); 5610 5647 _input[0].popFront; 5611 5648 _input[1].popFront; 5612 5649 adjustPosition; 5613 5650 } 5614 5651 5615 ElementType front()5652 @property ElementType front() 5616 5653 { 5617 5654 assert(!empty); 5618 5655 return _input[0].front; 5619 5656 } 5620 5657 } 5621 5658 5622 5659 /// Ditto 5623 5660 SetIntersection!(less, Rs) setIntersection(alias less = "a < b", Rs...) 5624 5661 (Rs ranges) 5625 5662 if (allSatisfy!(isInputRange, Rs)) … … 5690 5727 // position to the first element 5691 5728 adjustPosition; 5692 5729 } 5693 5730 5694 5731 void popFront() 5695 5732 { 5696 5733 r1.popFront; 5697 5734 adjustPosition; 5698 5735 } 5699 5736 5700 ElementType!(R1) front()5737 @property ElementType!(R1) front() 5701 5738 { 5702 5739 assert(!empty); 5703 5740 return r1.front; 5704 5741 } 5705 5742 5706 5743 bool empty() { return r1.empty; } 5707 5744 } 5708 5745 5709 5746 /// Ditto 5710 5747 SetDifference!(less, R1, R2) setDifference(alias less = "a < b", R1, R2) … … 5781 5818 } 5782 5819 else 5783 5820 { 5784 5821 assert(comp(r2.front, r1.front)); 5785 5822 r2.popFront; 5786 5823 } 5787 5824 } 5788 5825 adjustPosition; 5789 5826 } 5790 5827 5791 ElementType!(R1) front()5828 @property ElementType!(R1) front() 5792 5829 { 5793 5830 assert(!empty); 5794 5831 if (r2.empty || !r1.empty && comp(r1.front, r2.front)) 5795 5832 { 5796 5833 return r1.front; 5797 5834 } 5798 5835 assert(r1.empty || comp(r2.front, r1.front)); 5799 5836 return r2.front; 5800 5837 } 5801 5838 5802 5839 ref auto opSlice() { return this; } 5803 5840 5804 bool empty() { return r1.empty && r2.empty; }5841 @property bool empty() { return r1.empty && r2.empty; } 5805 5842 } 5806 5843 5807 5844 /// Ditto 5808 5845 SetSymmetricDifference!(less, R1, R2) 5809 5846 setSymmetricDifference(alias less = "a < b", R1, R2) 5810 5847 (R1 r1, R2 r2) 5811 5848 { 5812 5849 return typeof(return)(r1, r2); 5813 5850 } 5814 5851 … … 5931 5968 5932 5969 this(RangeOfRanges ror) 5933 5970 { 5934 5971 // Preemptively get rid of all empty ranges in the input 5935 5972 // No need for stability either 5936 5973 _ror = remove!("a.empty", SwapStrategy.unstable)(ror); 5937 5974 //Build the heap across the range 5938 5975 _heap.acquire(_ror); 5939 5976 } 5940 5977 5941 bool empty() { return _ror.empty; }5942 5943 ref ElementType front()5978 @property bool empty() { return _ror.empty; } 5979 5980 @property ref ElementType front() 5944 5981 { 5945 5982 return _heap.front.front; 5946 5983 } 5947 5984 5948 5985 void popFront() 5949 5986 { 5950 5987 _heap.removeFront(); 5951 5988 // let's look at the guy just popped 5952 5989 _ror.back.popFront; 5953 5990 if (_ror.back.empty)
