Changeset 1704
- Timestamp:
- 07/01/10 02:51:24 (14 years ago)
- Files:
-
- trunk/phobos/std/range.d (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/std/range.d
r1698 r1704 633 633 private: 634 634 R _input; 635 635 enum bool byRef = is(typeof(&(R.init.front()))); 636 636 637 637 public: 638 638 alias R Source; 639 639 640 640 /** 641 641 Forwards to $(D _input.empty). 642 642 */ 643 bool empty()643 @property bool empty() 644 644 { 645 645 return _input.empty; 646 646 } 647 647 648 648 /** 649 649 Returns a copy of $(D this). 650 650 */ 651 651 @property Retro save() 652 652 { 653 653 return Retro(_input.save); … … 831 831 { 832 832 @property Stride save() 833 833 { 834 834 return Stride(_input.save, _n); 835 835 } 836 836 } 837 837 838 838 /** 839 839 Forwards to $(D _input.empty). 840 840 */ 841 bool empty()841 @property bool empty() 842 842 { 843 843 return _input.empty; 844 844 } 845 845 846 846 /** 847 847 @@@ 848 848 */ 849 849 void popFront() 850 850 { 851 851 static if (isRandomAccessRange!(R) && hasLength!(R) && hasSlicing!(R)) … … 879 879 { 880 880 if (_input.empty) break; 881 881 _input.popBack; 882 882 } 883 883 } 884 884 } 885 885 886 886 /** 887 887 Forwards to $(D _input.front). 888 888 */ 889 ref ElementType!(R) front()889 @property ref ElementType!(R) front() 890 890 { 891 891 return _input.front; 892 892 } 893 893 894 894 /** 895 895 Forwards to $(D _input.back) after getting rid of any slack items. 896 896 */ 897 897 static if(isBidirectionalRange!(R) && hasLength!(R)) 898 898 { 899 ref ElementType!(R) back()899 @property ref ElementType!(R) back() 900 900 { 901 901 return _input.back; 902 902 } 903 903 } 904 904 905 905 /** 906 906 Forwards to $(D _input[_input.length - n + 1]). Defined only if $(D R) 907 907 is a random access range and if $(D R) defines $(D R.length). 908 908 */ 909 909 static if (isRandomAccessRange!(R) && hasLength!(R)) … … 1025 1025 alias RvalueElementType ElementType; 1026 1026 1027 1027 this(R input) 1028 1028 { 1029 1029 foreach (i, v; input) 1030 1030 { 1031 1031 _input.field[i] = v; 1032 1032 } 1033 1033 } 1034 1034 1035 bool empty()1035 @property bool empty() 1036 1036 { 1037 1037 foreach (i, Unused; R) 1038 1038 { 1039 1039 if (!_input.field[i].empty) return false; 1040 1040 } 1041 1041 return true; 1042 1042 } 1043 1043 1044 1044 static if (allSatisfy!(isForwardRange, R)) 1045 1045 ChainImpl save() … … 1328 1328 */ 1329 1329 ref Radial opSlice() 1330 1330 { 1331 1331 return this; 1332 1332 } 1333 1333 1334 1334 /** 1335 1335 Range primitive operation that returns $(D true) iff there are no more 1336 1336 elements to be iterated. 1337 1337 */ 1338 bool empty()1338 @property bool empty() 1339 1339 { 1340 1340 return _low.empty && _up.empty; 1341 1341 } 1342 1342 1343 1343 /** 1344 1344 Range primitive operation that advances the range to its next 1345 1345 element. 1346 1346 */ 1347 1347 void popFront() 1348 1348 { … … 1369 1369 if (!_up.empty) _up.popFront; 1370 1370 if (!_low.empty) _low.popBack; 1371 1371 if (!_low.empty) _upIsActive = false; 1372 1372 } 1373 1373 } 1374 1374 1375 1375 /** 1376 1376 Range primitive operation that returns the currently iterated 1377 1377 element. Throws if the range is empty. 1378 1378 */ 1379 ref ElementType!(R) front()1379 @property ref ElementType!(R) front() 1380 1380 { 1381 1381 enforce(!empty, "Calling front() against an empty " 1382 1382 ~typeof(this).stringof); 1383 1383 if (!_upIsActive) 1384 1384 { 1385 1385 // @@@ Damndest thing... removing the enforce below causes 1386 1386 // a segfault in release unittest 1387 1387 enforce(!_low.empty); 1388 1388 return _low.back; 1389 1389 } … … 1450 1450 enum bool byRef = is(typeof(&_input.front) == ElementType!(R)*); 1451 1451 1452 1452 public: 1453 1453 alias R Source; 1454 1454 1455 1455 static if (byRef) 1456 1456 alias ref .ElementType!(R) ElementType; 1457 1457 else 1458 1458 alias .ElementType!(R) ElementType; 1459 1459 1460 bool empty()1460 @property bool empty() 1461 1461 { 1462 1462 return _maxAvailable == 0 || original.empty; 1463 1463 } 1464 1464 1465 1465 static if (isForwardRange!R) 1466 1466 @property Take save() 1467 1467 { 1468 1468 return Take(original.save, _maxAvailable); 1469 1469 } 1470 1470 … … 1734 1734 Tip: This is a great way to implement simple circular buffers. 1735 1735 */ 1736 1736 struct Cycle(R) if (isForwardRange!(R) && !isInfinite!(R)) 1737 1737 { 1738 1738 static if (isRandomAccessRange!(R) && hasLength!(R)) 1739 1739 { 1740 1740 R _original; 1741 1741 size_t _index; 1742 1742 this(R input, size_t index = 0) { _original = input; _index = index; } 1743 1743 /// Range primitive implementations. 1744 ref ElementType!(R) front()1744 @property ref ElementType!(R) front() 1745 1745 { 1746 1746 return _original[_index % _original.length]; 1747 1747 } 1748 1748 /// Ditto 1749 1749 enum bool empty = false; 1750 1750 /// Ditto 1751 1751 void popFront() { ++_index; } 1752 1752 ref ElementType!(R) opIndex(size_t n) 1753 1753 { 1754 1754 return _original[(n + _index) % _original.length]; … … 1756 1756 /// Ditto 1757 1757 @property Cycle!(R) save() { 1758 1758 return Cycle!(R)(this._original.save, this._index); 1759 1759 } 1760 1760 } 1761 1761 else 1762 1762 { 1763 1763 R _original, _current; 1764 1764 this(R input) { _original = input; _current = input.save; } 1765 1765 /// Range primitive implementations. 1766 ref ElementType!(R) front() { return _current.front; }1766 @property ref ElementType!(R) front() { return _current.front; } 1767 1767 /// Ditto 1768 1768 static if (isBidirectionalRange!(R)) 1769 ref ElementType!(R) back() { return _current.back; }1769 @property ref ElementType!(R) back() { return _current.back; } 1770 1770 /// Ditto 1771 1771 enum bool empty = false; 1772 1772 /// Ditto 1773 1773 void popFront() 1774 1774 { 1775 1775 _current.popFront; 1776 1776 if (_current.empty) _current = _original; 1777 1777 } 1778 1778 1779 1779 @property Cycle!(R) save() { … … 1798 1798 private alias typeof(R[0]) ElementType; 1799 1799 private ElementType* _ptr; 1800 1800 private size_t _index; 1801 1801 1802 1802 this(ref R input, size_t index = 0) 1803 1803 { 1804 1804 _ptr = input.ptr; 1805 1805 _index = index; 1806 1806 } 1807 1807 /// Range primitive implementations. 1808 ref ElementType front()1808 @property ref ElementType front() 1809 1809 { 1810 1810 return _ptr[_index % R.length]; 1811 1811 } 1812 1812 /// Ditto 1813 1813 enum bool empty = false; 1814 1814 /// Ditto 1815 1815 void popFront() { ++_index; } 1816 1816 ref ElementType opIndex(size_t n) 1817 1817 { 1818 1818 return _ptr[(n + _index) % R.length]; … … 1971 1971 foreach (i, Unused; R) 1972 1972 { 1973 1973 result.ranges.field[i] = ranges.field[i].save; 1974 1974 } 1975 1975 return result; 1976 1976 } 1977 1977 1978 1978 /** 1979 1979 Returns a proxy for the current iterated element. 1980 1980 */ 1981 Proxy front()1981 @property Proxy front() 1982 1982 { 1983 1983 Proxy result; 1984 1984 foreach (i, Unused; R) 1985 1985 { 1986 1986 result.ptrs.field[i] = &ranges.field[i].front; 1987 1987 } 1988 1988 return result; 1989 1989 } 1990 1990 1991 1991 /** 1992 1992 Returns a proxy for the rightmost element. 1993 1993 */ 1994 Proxy back()1994 @property Proxy back() 1995 1995 { 1996 1996 Proxy result; 1997 1997 foreach (i, Unused; R) 1998 1998 { 1999 1999 result.ptrs.field[i] = &ranges.field[i].back; 2000 2000 } 2001 2001 return result; 2002 2002 } 2003 2003 2004 2004 /** … … 2211 2211 2212 2212 this(StateType[stateSize] initial) { _state = initial; } 2213 2213 2214 2214 void popFront() 2215 2215 { 2216 2216 _state[_n % stateSize] = binaryFun!(fun, "a", "n")( 2217 2217 cycle(_state, _n), _n + stateSize); 2218 2218 ++_n; 2219 2219 } 2220 2220 2221 StateType front()2221 @property StateType front() 2222 2222 { 2223 2223 return _state[_n % stateSize]; 2224 2224 } 2225 2225 2226 2226 enum bool empty = false; 2227 2227 } 2228 2228 2229 2229 /// Ditto 2230 2230 Recurrence!(fun, CommonType!(State), State.length) 2231 2231 recurrence(alias fun, State...)(State initial) … … 2281 2281 ElementType _cache; 2282 2282 2283 2283 public: 2284 2284 this(State initial, size_t n = 0) 2285 2285 { 2286 2286 this._state = initial; 2287 2287 this._n = n; 2288 2288 this._cache = compute(this._state, this._n); 2289 2289 } 2290 2290 2291 ElementType front()2291 @property ElementType front() 2292 2292 { 2293 2293 //return ElementType.init; 2294 2294 return this._cache; 2295 2295 } 2296 2296 2297 2297 ElementType moveFront() 2298 2298 { 2299 2299 return move(_cache); 2300 2300 } 2301 2301 … … 2626 2626 foreach (e; _input) 2627 2627 { 2628 2628 enforce(e.length == commonLength); 2629 2629 } 2630 2630 } 2631 2631 } 2632 2632 2633 2633 /** 2634 2634 Forward range primitives. 2635 2635 */ 2636 bool empty()2636 @property bool empty() 2637 2637 { 2638 2638 return _input.empty; 2639 2639 } 2640 2640 2641 2641 /// Ditto 2642 ref ElementType front()2642 @property ref ElementType front() 2643 2643 { 2644 2644 assert(!empty); 2645 2645 return _input.front.front; 2646 2646 } 2647 2647 2648 2648 /// Ditto 2649 2649 void popFront() 2650 2650 { 2651 2651 assert(!empty); 2652 2652 _input.popFront; 2653 2653 prime; 2654 2654 } 2655 2655 2656 2656 static if (isBidirectionalRange!RangeOfRanges) 2657 2657 { 2658 2658 /** 2659 2659 Bidirectional primitives. They are offered if $(D 2660 2660 isBidirectionalRange!RangeOfRanges). 2661 2661 */ 2662 ref ElementType back()2662 @property ref ElementType back() 2663 2663 { 2664 2664 return _input.back.front; 2665 2665 } 2666 2666 /// Ditto 2667 2667 void popBack() 2668 2668 { 2669 2669 assert(!empty); 2670 2670 _input.popBack; 2671 2671 prime; 2672 2672 } … … 2765 2765 foreach (e; _input) 2766 2766 { 2767 2767 enforce(e.length == commonLength); 2768 2768 } 2769 2769 } 2770 2770 } 2771 2771 2772 2772 /** 2773 2773 Forward range primitives. 2774 2774 */ 2775 bool empty()2775 @property bool empty() 2776 2776 { 2777 2777 return _input.empty; 2778 2778 } 2779 2779 2780 2780 /// Ditto 2781 ref ElementType front()2781 @property ref ElementType front() 2782 2782 { 2783 2783 assert(!empty); 2784 2784 return _input.front[_n]; 2785 2785 } 2786 2786 2787 2787 /// Ditto 2788 2788 void popFront() 2789 2789 { 2790 2790 assert(!empty); 2791 2791 _input.popFront; 2792 2792 prime; 2793 2793 } 2794 2794 2795 2795 static if (isBidirectionalRange!RangeOfRanges) 2796 2796 { 2797 2797 /** 2798 2798 Bidirectional primitives. They are offered if $(D 2799 2799 isBidirectionalRange!RangeOfRanges). 2800 2800 */ 2801 ref ElementType back()2801 @property ref ElementType back() 2802 2802 { 2803 2803 return _input.back[_n]; 2804 2804 } 2805 2805 void popBack() 2806 2806 { 2807 2807 assert(!empty); 2808 2808 _input.popBack; 2809 2809 prime; 2810 2810 } 2811 2811 } … … 2863 2863 2864 2864 struct Transposed(RangeOfRanges) 2865 2865 { 2866 2866 alias typeof(map!"a.front"(RangeOfRanges.init)) ElementType; 2867 2867 2868 2868 this(RangeOfRanges input) 2869 2869 { 2870 2870 this._input = input; 2871 2871 } 2872 2872 2873 ElementType front()2873 @property ElementType front() 2874 2874 { 2875 2875 return map!"a.front"(_input); 2876 2876 } 2877 2877 2878 2878 void popFront() 2879 2879 { 2880 2880 foreach (ref e; _input) 2881 2881 { 2882 2882 if (e.empty) continue; 2883 2883 e.popFront; 2884 2884 } 2885 2885 } 2886 2886 2887 2887 // ElementType opIndex(size_t n) 2888 2888 // { 2889 2889 // return _input[n].front; 2890 2890 // } 2891 2891 2892 bool empty()2892 @property bool empty() 2893 2893 { 2894 2894 foreach (e; _input) 2895 2895 if (!e.empty) return false; 2896 2896 return true; 2897 2897 } 2898 2898 2899 2899 @property Transposed save() 2900 2900 { 2901 2901 return Transposed(_input.save); 2902 2902 }
