 |
Changeset 3966
- Timestamp:
- 10/04/08 22:10:48
(2 months ago)
- Author:
- kris
- Message:
Updated iterators to expose pointers, and doubled traversal rate
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r3923 |
r3966 |
|
| 29 | 29 | --- |
|---|
| 30 | 30 | Iterator iterator () |
|---|
| 31 | | IteratorMatch iterator (V value) |
|---|
| 32 | 31 | uint opApply (int delegate(ref V value) dg) |
|---|
| 33 | 32 | |
|---|
| … | … | |
| 154 | 153 | i.cell = list; |
|---|
| 155 | 154 | i.head = list; |
|---|
| | 155 | i.bump = &Iterator.fore; |
|---|
| 156 | 156 | return i; |
|---|
| 157 | 157 | } |
|---|
| … | … | |
| 159 | 159 | /*********************************************************************** |
|---|
| 160 | 160 | |
|---|
| 161 | | Return an iterator which filters on the provided value |
|---|
| 162 | | |
|---|
| 163 | | ***********************************************************************/ |
|---|
| 164 | | |
|---|
| 165 | | final IteratorMatch iterator (V value) |
|---|
| 166 | | { |
|---|
| 167 | | IteratorMatch m = void; |
|---|
| 168 | | m.host = iterator; |
|---|
| 169 | | m.match = value; |
|---|
| 170 | | return m; |
|---|
| 171 | | } |
|---|
| 172 | | |
|---|
| 173 | | /*********************************************************************** |
|---|
| 174 | | |
|---|
| 175 | 161 | |
|---|
| 176 | 162 | ***********************************************************************/ |
|---|
| … | … | |
| 178 | 164 | final int opApply (int delegate(ref V value) dg) |
|---|
| 179 | 165 | { |
|---|
| 180 | | auto freach = iterator.freach; |
|---|
| 181 | | return freach.opApply (dg); |
|---|
| | 166 | return iterator.opApply (dg); |
|---|
| 182 | 167 | } |
|---|
| 183 | 168 | |
|---|
| … | … | |
| 938 | 923 | /*********************************************************************** |
|---|
| 939 | 924 | |
|---|
| 940 | | foreach support for iterators |
|---|
| 941 | | |
|---|
| 942 | | ***********************************************************************/ |
|---|
| 943 | | |
|---|
| 944 | | private struct Freach |
|---|
| 945 | | { |
|---|
| 946 | | bool delegate(ref V) next; |
|---|
| 947 | | |
|---|
| | 925 | Iterator with no filtering |
|---|
| | 926 | |
|---|
| | 927 | ***********************************************************************/ |
|---|
| | 928 | |
|---|
| | 929 | private struct Iterator |
|---|
| | 930 | { |
|---|
| | 931 | Ref function(Ref) bump; |
|---|
| | 932 | Ref cell, |
|---|
| | 933 | head, |
|---|
| | 934 | prior; |
|---|
| | 935 | CircularList owner; |
|---|
| | 936 | uint mutation; |
|---|
| | 937 | |
|---|
| | 938 | /*************************************************************** |
|---|
| | 939 | |
|---|
| | 940 | Did the container change underneath us? |
|---|
| | 941 | |
|---|
| | 942 | ***************************************************************/ |
|---|
| | 943 | |
|---|
| | 944 | bool valid () |
|---|
| | 945 | { |
|---|
| | 946 | return owner.mutation is mutation; |
|---|
| | 947 | } |
|---|
| | 948 | |
|---|
| | 949 | /*************************************************************** |
|---|
| | 950 | |
|---|
| | 951 | Accesses the next value, and returns false when |
|---|
| | 952 | there are no further values to traverse |
|---|
| | 953 | |
|---|
| | 954 | ***************************************************************/ |
|---|
| | 955 | |
|---|
| | 956 | bool next (ref V v) |
|---|
| | 957 | { |
|---|
| | 958 | auto n = next; |
|---|
| | 959 | return (n) ? v = *n, true : false; |
|---|
| | 960 | } |
|---|
| | 961 | |
|---|
| | 962 | /*************************************************************** |
|---|
| | 963 | |
|---|
| | 964 | Return a pointer to the next value, or null when |
|---|
| | 965 | there are no further values to traverse |
|---|
| | 966 | |
|---|
| | 967 | ***************************************************************/ |
|---|
| | 968 | |
|---|
| | 969 | V* next () |
|---|
| | 970 | { |
|---|
| | 971 | V* r; |
|---|
| | 972 | |
|---|
| | 973 | if (cell) |
|---|
| | 974 | { |
|---|
| | 975 | prior = cell; |
|---|
| | 976 | r = &cell.value; |
|---|
| | 977 | cell = bump (cell); |
|---|
| | 978 | if (cell is head) |
|---|
| | 979 | cell = null; |
|---|
| | 980 | } |
|---|
| | 981 | return r; |
|---|
| | 982 | } |
|---|
| | 983 | |
|---|
| | 984 | /*************************************************************** |
|---|
| | 985 | |
|---|
| | 986 | Foreach support |
|---|
| | 987 | |
|---|
| | 988 | ***************************************************************/ |
|---|
| | 989 | |
|---|
| 948 | 990 | int opApply (int delegate(ref V value) dg) |
|---|
| 949 | 991 | { |
|---|
| 950 | | V value; |
|---|
| 951 | 992 | int result; |
|---|
| 952 | 993 | |
|---|
| 953 | | while (next (value)) |
|---|
| 954 | | if ((result = dg(value)) != 0) |
|---|
| 955 | | break; |
|---|
| | 994 | auto c = cell; |
|---|
| | 995 | while (c) |
|---|
| | 996 | { |
|---|
| | 997 | prior = c; |
|---|
| | 998 | if ((c = bump(c)) is head) |
|---|
| | 999 | c = null; |
|---|
| | 1000 | if ((result = dg(prior.value)) != 0) |
|---|
| | 1001 | break; |
|---|
| | 1002 | } |
|---|
| | 1003 | cell = c; |
|---|
| 956 | 1004 | return result; |
|---|
| 957 | | } |
|---|
| 958 | | } |
|---|
| 959 | | |
|---|
| 960 | | /*********************************************************************** |
|---|
| 961 | | |
|---|
| 962 | | Iterator with no filtering |
|---|
| 963 | | |
|---|
| 964 | | ***********************************************************************/ |
|---|
| 965 | | |
|---|
| 966 | | private struct Iterator |
|---|
| 967 | | { |
|---|
| 968 | | Ref cell, |
|---|
| 969 | | head, |
|---|
| 970 | | prior; |
|---|
| 971 | | CircularList owner; |
|---|
| 972 | | uint mutation; |
|---|
| 973 | | |
|---|
| 974 | | bool prev (ref V v) |
|---|
| 975 | | { |
|---|
| 976 | | if (cell is null) |
|---|
| 977 | | return false; |
|---|
| 978 | | |
|---|
| 979 | | prior = cell; |
|---|
| 980 | | v = cell.value; |
|---|
| 981 | | cell = cell.prev; |
|---|
| 982 | | if (cell is head) |
|---|
| 983 | | cell = null; |
|---|
| 984 | | return true; |
|---|
| 985 | | } |
|---|
| 986 | | |
|---|
| 987 | | bool next (ref V v) |
|---|
| 988 | | { |
|---|
| 989 | | if (cell is null) |
|---|
| 990 | | return false; |
|---|
| 991 | | |
|---|
| 992 | | prior = cell; |
|---|
| 993 | | v = cell.value; |
|---|
| 994 | | cell = cell.next; |
|---|
| 995 | | if (cell is head) |
|---|
| 996 | | cell = null; |
|---|
| 997 | | return true; |
|---|
| 998 | | } |
|---|
| 999 | | |
|---|
| 1000 | | void remove () |
|---|
| | 1005 | } |
|---|
| | 1006 | |
|---|
| | 1007 | /*************************************************************** |
|---|
| | 1008 | |
|---|
| | 1009 | Remove value at the current iterator location |
|---|
| | 1010 | |
|---|
| | 1011 | ***************************************************************/ |
|---|
| | 1012 | |
|---|
| | 1013 | bool remove () |
|---|
| 1001 | 1014 | { |
|---|
| 1002 | 1015 | if (prior) |
|---|
| 1003 | 1016 | { |
|---|
| 1004 | | auto next = prior.next; |
|---|
| 1005 | | if (prior is owner.list) |
|---|
| | 1017 | auto next = bump (prior); |
|---|
| | 1018 | if (prior is head) |
|---|
| 1006 | 1019 | if (prior is next) |
|---|
| 1007 | 1020 | owner.list = null; |
|---|
| 1008 | 1021 | else |
|---|
| 1009 | | owner.list = next; |
|---|
| | 1022 | head = next; |
|---|
| 1010 | 1023 | |
|---|
| 1011 | 1024 | prior.unlink; |
|---|
| … | … | |
| 1015 | 1028 | // ignore this change |
|---|
| 1016 | 1029 | ++mutation; |
|---|
| | 1030 | return true; |
|---|
| 1017 | 1031 | } |
|---|
| 1018 | | } |
|---|
| 1019 | | |
|---|
| 1020 | | bool valid () |
|---|
| 1021 | | { |
|---|
| 1022 | | return owner.mutation is mutation; |
|---|
| 1023 | | } |
|---|
| 1024 | | |
|---|
| 1025 | | Freach freach() |
|---|
| 1026 | | { |
|---|
| 1027 | | Freach f = {&next}; |
|---|
| 1028 | | return f; |
|---|
| 1029 | | } |
|---|
| 1030 | | |
|---|
| 1031 | | Freach reverse() |
|---|
| 1032 | | { |
|---|
| 1033 | | cell = cell.prev; |
|---|
| 1034 | | head = head.prev; |
|---|
| 1035 | | Freach f = {&prev}; |
|---|
| 1036 | | return f; |
|---|
| 1037 | | } |
|---|
| 1038 | | } |
|---|
| 1039 | | |
|---|
| 1040 | | /*********************************************************************** |
|---|
| 1041 | | |
|---|
| 1042 | | Iterator with value filtering |
|---|
| 1043 | | |
|---|
| 1044 | | ***********************************************************************/ |
|---|
| 1045 | | |
|---|
| 1046 | | private struct IteratorMatch |
|---|
| 1047 | | { |
|---|
| 1048 | | Iterator host; |
|---|
| 1049 | | V match; |
|---|
| 1050 | | |
|---|
| 1051 | | bool next (ref V v) |
|---|
| 1052 | | { |
|---|
| 1053 | | while (host.next (v)) |
|---|
| 1054 | | if (match == v) |
|---|
| 1055 | | return true; |
|---|
| 1056 | 1032 | return false; |
|---|
| 1057 | 1033 | } |
|---|
| 1058 | 1034 | |
|---|
| 1059 | | void remove () |
|---|
| | 1035 | /*************************************************************** |
|---|
| | 1036 | |
|---|
| | 1037 | ***************************************************************/ |
|---|
| | 1038 | |
|---|
| | 1039 | Iterator reverse () |
|---|
| 1060 | 1040 | { |
|---|
| 1061 | | host.remove; |
|---|
| | 1041 | if (bump is &fore) |
|---|
| | 1042 | bump = &back; |
|---|
| | 1043 | else |
|---|
| | 1044 | bump = &fore; |
|---|
| | 1045 | return *this; |
|---|
| 1062 | 1046 | } |
|---|
| 1063 | | |
|---|
| 1064 | | bool valid () |
|---|
| | 1047 | |
|---|
| | 1048 | /*************************************************************** |
|---|
| | 1049 | |
|---|
| | 1050 | ***************************************************************/ |
|---|
| | 1051 | |
|---|
| | 1052 | private static Ref fore (Ref p) |
|---|
| 1065 | 1053 | { |
|---|
| 1066 | | return host.valid; |
|---|
| | 1054 | return p.next; |
|---|
| 1067 | 1055 | } |
|---|
| 1068 | | |
|---|
| 1069 | | Freach freach() |
|---|
| | 1056 | |
|---|
| | 1057 | /*************************************************************** |
|---|
| | 1058 | |
|---|
| | 1059 | ***************************************************************/ |
|---|
| | 1060 | |
|---|
| | 1061 | private static Ref back (Ref p) |
|---|
| 1070 | 1062 | { |
|---|
| 1071 | | Freach f = {&next}; |
|---|
| 1072 | | return f; |
|---|
| | 1063 | return p.prev; |
|---|
| 1073 | 1064 | } |
|---|
| 1074 | 1065 | } |
|---|
| … | … | |
| 1102 | 1093 | |
|---|
| 1103 | 1094 | // explicit generic iteration |
|---|
| 1104 | | foreach (value; list.iterator.freach) |
|---|
| | 1095 | foreach (value; list.iterator.reverse) |
|---|
| 1105 | 1096 | Stdout.formatln ("> {}", value); |
|---|
| 1106 | | |
|---|
| 1107 | | // generic filtered iteration |
|---|
| 1108 | | foreach (value; list.iterator("foo").freach) |
|---|
| 1109 | | Stdout (value).newline; |
|---|
| 1110 | | |
|---|
| 1111 | | // generic filtered iteration |
|---|
| 1112 | | foreach (value; list.iterator.reverse) |
|---|
| 1113 | | Stdout.formatln ("< {}", value); |
|---|
| 1114 | 1097 | |
|---|
| 1115 | 1098 | // generic iteration with optional remove |
|---|
| 1116 | 1099 | auto s = list.iterator; |
|---|
| 1117 | | foreach (value; s.freach) |
|---|
| 1118 | | {} // s.remove; |
|---|
| | 1100 | foreach (value; s) |
|---|
| | 1101 | {} //s.remove; |
|---|
| 1119 | 1102 | |
|---|
| 1120 | 1103 | // incremental iteration, with optional remove |
|---|
| … | … | |
| 1122 | 1105 | auto iterator = list.iterator; |
|---|
| 1123 | 1106 | while (iterator.next(v)) |
|---|
| 1124 | | {} //iterator.remove; |
|---|
| | 1107 | {}//iterator.remove; |
|---|
| 1125 | 1108 | |
|---|
| 1126 | 1109 | // incremental iteration, with optional failfast |
|---|
| r3868 |
r3966 |
|
| 31 | 31 | --- |
|---|
| 32 | 32 | Iterator iterator () |
|---|
| 33 | | IteratorMatch iterator (V value) |
|---|
| 34 | 33 | int opApply (int delegate(ref V value) dg) |
|---|
| 35 | 34 | int opApply (int delegate(ref K key, ref V value) dg) |
|---|
| … | … | |
| 147 | 146 | /*********************************************************************** |
|---|
| 148 | 147 | |
|---|
| 149 | | Return an iterator which filters on the provided key |
|---|
| 150 | | |
|---|
| 151 | | ***********************************************************************/ |
|---|
| 152 | | |
|---|
| 153 | | final IteratorMatch iterator (V value) |
|---|
| 154 | | { |
|---|
| 155 | | IteratorMatch m = void; |
|---|
| 156 | | m.host = iterator; |
|---|
| 157 | | m.match = value; |
|---|
| 158 | | return m; |
|---|
| 159 | | } |
|---|
| 160 | | |
|---|
| 161 | | /*********************************************************************** |
|---|
| 162 | | |
|---|
| 163 | 148 | |
|---|
| 164 | 149 | ***********************************************************************/ |
|---|
| … | … | |
| 166 | 151 | final int opApply (int delegate(ref K key, ref V value) dg) |
|---|
| 167 | 152 | { |
|---|
| 168 | | auto freach = iterator.freach; |
|---|
| 169 | | return freach.opApply (dg); |
|---|
| | 153 | return iterator.opApply (dg); |
|---|
| 170 | 154 | } |
|---|
| 171 | 155 | |
|---|
| … | … | |
| 177 | 161 | final int opApply (int delegate(ref V value) dg) |
|---|
| 178 | 162 | { |
|---|
| 179 | | auto freach = iterator.freach; |
|---|
| 180 | | return freach.opApply ((ref K k, ref V v) {return dg(v);}); |
|---|
| | 163 | return iterator.opApply ((ref K k, ref V v) {return dg(v);}); |
|---|
| 181 | 164 | } |
|---|
| 182 | 165 | |
|---|
| … | … | |
| 370 | 353 | clone.buckets (buckets); |
|---|
| 371 | 354 | |
|---|
| 372 | | foreach (key, value; iterator.freach) |
|---|
| | 355 | foreach (key, value; iterator) |
|---|
| 373 | 356 | clone.add (key, value); |
|---|
| 374 | 357 | } |
|---|
| … | … | |
| 967 | 950 | /*********************************************************************** |
|---|
| 968 | 951 | |
|---|
| 969 | | foreach support for iterators |
|---|
| 970 | | |
|---|
| 971 | | ***********************************************************************/ |
|---|
| 972 | | |
|---|
| 973 | | private struct Freach |
|---|
| 974 | | { |
|---|
| 975 | | bool delegate(ref K, ref V) next; |
|---|
| 976 | | |
|---|
| 977 | | int opApply (int delegate(ref K key, ref V value) dg) |
|---|
| 978 | | { |
|---|
| 979 | | K key; |
|---|
| 980 | | V value; |
|---|
| 981 | | int result; |
|---|
| 982 | | |
|---|
| 983 | | while (next (key, value)) |
|---|
| 984 | | if ((result = dg(key, value)) != 0) |
|---|
| 985 | | break; |
|---|
| 986 | | return result; |
|---|
| 987 | | } |
|---|
| 988 | | } |
|---|
| 989 | | |
|---|
| 990 | | /*********************************************************************** |
|---|
| 991 | | |
|---|
| 992 | 952 | Iterator with no filtering |
|---|
| 993 | 953 | |
|---|
| … | … | |
| 1003 | 963 | uint mutation; |
|---|
| 1004 | 964 | |
|---|
| | 965 | /*************************************************************** |
|---|
| | 966 | |
|---|
| | 967 | Did the container change underneath us? |
|---|
| | 968 | |
|---|
| | 969 | ***************************************************************/ |
|---|
| | 970 | |
|---|
| | 971 | bool valid () |
|---|
| | 972 | { |
|---|
| | 973 | return owner.mutation is mutation; |
|---|
| | 974 | } |
|---|
| | 975 | |
|---|
| | 976 | /*************************************************************** |
|---|
| | 977 | |
|---|
| | 978 | Accesses the next value, and returns false when |
|---|
| | 979 | there are no further values to traverse |
|---|
| | 980 | |
|---|
| | 981 | ***************************************************************/ |
|---|
| | 982 | |
|---|
| 1005 | 983 | bool next (ref K k, ref V v) |
|---|
| | 984 | { |
|---|
| | 985 | auto n = next (k); |
|---|
| | 986 | return (n) ? v = *n, true : false; |
|---|
| | 987 | } |
|---|
| | 988 | |
|---|
| | 989 | /*************************************************************** |
|---|
| | 990 | |
|---|
| | 991 | Return a pointer to the next value, or null when |
|---|
| | 992 | there are no further values to traverse |
|---|
| | 993 | |
|---|
| | 994 | ***************************************************************/ |
|---|
| | 995 | |
|---|
| | 996 | V* next (ref K k) |
|---|
| 1006 | 997 | { |
|---|
| 1007 | 998 | while (cell is null) |
|---|
| … | … | |
| 1009 | 1000 | cell = table [row++]; |
|---|
| 1010 | 1001 | else |
|---|
| 1011 | | return false; |
|---|
| | 1002 | return null; |
|---|
| 1012 | 1003 | |
|---|
| 1013 | 1004 | prior = cell; |
|---|
| 1014 | 1005 | k = cell.key; |
|---|
| 1015 | | v = cell.value; |
|---|
| 1016 | 1006 | cell = cell.next; |
|---|
| 1017 | | return true; |
|---|
| | 1007 | return &prior.value; |
|---|
| | 1008 | |
|---|
| 1018 | 1009 | } |
|---|
| 1019 | 1010 | |
|---|
| 1020 | | void remove () |
|---|
| | 1011 | /*************************************************************** |
|---|
| | 1012 | |
|---|
| | 1013 | Foreach support |
|---|
| | 1014 | |
|---|
| | 1015 | ***************************************************************/ |
|---|
| | 1016 | |
|---|
| | 1017 | int opApply (int delegate(ref K key, ref V value) dg) |
|---|
| | 1018 | { |
|---|
| | 1019 | int result; |
|---|
| | 1020 | |
|---|
| | 1021 | auto c = cell; |
|---|
| | 1022 | loop: while (true) |
|---|
| | 1023 | { |
|---|
| | 1024 | while (c is null) |
|---|
| | 1025 | if (row < table.length) |
|---|
| | 1026 | c = table [row++]; |
|---|
| | 1027 | else |
|---|
| | 1028 | break loop; |
|---|
| | 1029 | |
|---|
| | 1030 | prior = c; |
|---|
| | 1031 | c = c.next; |
|---|
| | 1032 | if ((result = dg(prior.key, prior.value)) != 0) |
|---|
| | 1033 | break loop; |
|---|
| | 1034 | } |
|---|
| | 1035 | |
|---|
| | 1036 | cell = c; |
|---|
| | 1037 | return result; |
|---|
| | 1038 | } |
|---|
| | 1039 | |
|---|
| | 1040 | /*************************************************************** |
|---|
| | 1041 | |
|---|
| | 1042 | Remove value at the current iterator location |
|---|
| | 1043 | |
|---|
| | 1044 | ***************************************************************/ |
|---|
| | 1045 | |
|---|
| | 1046 | bool remove () |
|---|
| 1021 | 1047 | { |
|---|
| 1022 | 1048 | if (prior) |
|---|
| 1023 | 1049 | if (owner.removeNode (prior, &table[row-1])) |
|---|
| 1024 | | // ignore this change |
|---|
| 1025 | | ++mutation; |
|---|
| | 1050 | { |
|---|
| | 1051 | // ignore this change |
|---|
| | 1052 | ++mutation; |
|---|
| | 1053 | return true; |
|---|
| | 1054 | } |
|---|
| | 1055 | |
|---|
| 1026 | 1056 | prior = null; |
|---|
| 1027 | | } |
|---|
| 1028 | | |
|---|
| 1029 | | bool valid () |
|---|
| 1030 | | { |
|---|
| 1031 | | return owner.mutation is mutation; |
|---|
| 1032 | | } |
|---|
| 1033 | | |
|---|
| 1034 | | Freach freach() |
|---|
| 1035 | | { |
|---|
| 1036 | | Freach f = {&next}; |
|---|
| 1037 | | return f; |
|---|
| 1038 | | } |
|---|
| 1039 | | } |
|---|
| 1040 | | |
|---|
| 1041 | | /*********************************************************************** |
|---|
| 1042 | | |
|---|
| 1043 | | Iterator with value filtering |
|---|
| 1044 | | |
|---|
| 1045 | | ***********************************************************************/ |
|---|
| 1046 | | |
|---|
| 1047 | | private struct IteratorMatch |
|---|
| 1048 | | { |
|---|
| 1049 | | Iterator host; |
|---|
| 1050 | | V match; |
|---|
| 1051 | | |
|---|
| 1052 | | bool next (ref K k, ref V v) |
|---|
| 1053 | | { |
|---|
| 1054 | | while (host.next (k, v)) |
|---|
| 1055 | | if (match == v) |
|---|
| 1056 | | return true; |
|---|
| 1057 | 1057 | return false; |
|---|
| 1058 | | } |
|---|
| 1059 | | |
|---|
| 1060 | | void remove () |
|---|
| 1061 | | { |
|---|
| 1062 | | host.remove; |
|---|
| 1063 | | } |
|---|
| 1064 | | |
|---|
| 1065 | | bool valid () |
|---|
| 1066 | | { |
|---|
| 1067 | | return host.valid; |
|---|
| 1068 | | } |
|---|
| 1069 | | |
|---|
| 1070 | | Freach freach() |
|---|
| 1071 | | { |
|---|
| 1072 | | Freach f = {&next}; |
|---|
| 1073 | | return f; |
|---|
| 1074 | 1058 | } |
|---|
| 1075 | 1059 | } |
|---|
| … | … | |
| 1100 | 1084 | |
|---|
| 1101 | 1085 | // explicit generic iteration |
|---|
| 1102 | | foreach (key, value; map.iterator.freach) |
|---|
| 1103 | | Stdout.formatln ("{}:{}", key, value); |
|---|
| 1104 | | |
|---|
| 1105 | | // generic filtered iteration |
|---|
| 1106 | | foreach (key, value; map.iterator(2).freach) |
|---|
| | 1086 | foreach (key, value; map.iterator) |
|---|
| 1107 | 1087 | Stdout.formatln ("{}:{}", key, value); |
|---|
| 1108 | 1088 | |
|---|
| 1109 | 1089 | // generic iteration with optional remove |
|---|
| 1110 | 1090 | auto s = map.iterator; |
|---|
| 1111 | | foreach (key, value; s.freach) |
|---|
| | 1091 | foreach (key, value; s) |
|---|
| 1112 | 1092 | {} // s.remove; |
|---|
| 1113 | 1093 | |
|---|
| r3713 |
r3966 |
|
| 137 | 137 | final int opApply (int delegate(ref V value) dg) |
|---|
| 138 | 138 | { |
|---|
| 139 | | auto freach = iterator.freach; |
|---|
| 140 | | return freach.opApply (dg); |
|---|
| | 139 | return iterator.opApply (dg); |
|---|
| 141 | 140 | } |
|---|
| 142 | 141 | |
|---|
| … | … | |
| 218 | 217 | clone.buckets (buckets); |
|---|
| 219 | 218 | |
|---|
| 220 | | foreach (value; iterator.freach) |
|---|
| | 219 | foreach (value; iterator) |
|---|
| 221 | 220 | clone.add (value); |
|---|
| 222 | 221 | } |
|---|
| … | … | |
| 679 | 678 | /*********************************************************************** |
|---|
| 680 | 679 | |
|---|
| 681 | | foreach support for iterators |
|---|
| 682 | | |
|---|
| 683 | | ***********************************************************************/ |
|---|
| 684 | | |
|---|
| 685 | | private struct Freach |
|---|
| 686 | | { |
|---|
| 687 | | bool delegate(ref V) next; |
|---|
| 688 | | |
|---|
| 689 | | int opApply (int delegate(ref V value) dg) |
|---|
| 690 | | { |
|---|
| 691 | | V value; |
|---|
| 692 | | int result; |
|---|
| 693 | | |
|---|
| 694 | | while (next (value)) |
|---|
| 695 | | if ((result = dg(value)) != 0) |
|---|
| 696 | | break; |
|---|
| 697 | | return result; |
|---|
| 698 | | } |
|---|
| 699 | | } |
|---|
| 700 | | |
|---|
| 701 | | /*********************************************************************** |
|---|
| 702 | | |
|---|
| 703 | 680 | Iterator with no filtering |
|---|
| 704 | 681 | |
|---|
| … | … | |
| 714 | 691 | uint mutation; |
|---|
| 715 | 692 | |
|---|
| | 693 | /*************************************************************** |
|---|
| | 694 | |
|---|
| | 695 | Did the container change underneath us? |
|---|
| | 696 | |
|---|
| | 697 | ***************************************************************/ |
|---|
| | 698 | |
|---|
| | 699 | bool valid () |
|---|
| | 700 | { |
|---|
| | 701 | return owner.mutation is mutation; |
|---|
| | 702 | } |
|---|
| | 703 | |
|---|
| | 704 | /*************************************************************** |
|---|
| | 705 | |
|---|
| | 706 | Accesses the next value, and returns false when |
|---|
| | 707 | there are no further values to traverse |
|---|
| | 708 | |
|---|
| | 709 | ***************************************************************/ |
|---|
| | 710 | |
|---|
| 716 | 711 | bool next (ref V v) |
|---|
| | 712 | { |
|---|
| | 713 | auto n = next; |
|---|
| | 714 | return (n) ? v = *n, true : false; |
|---|
| | 715 | } |
|---|
| | 716 | |
|---|
| | 717 | /*************************************************************** |
|---|
| | 718 | |
|---|
| | 719 | Return a pointer to the next value, or null when |
|---|
| | 720 | there are no further values to traverse |
|---|
| | 721 | |
|---|
| | 722 | ***************************************************************/ |
|---|
| | 723 | |
|---|
| | 724 | V* next () |
|---|
| 717 | 725 | { |
|---|
| 718 | 726 | while (cell is null) |
|---|
| … | … | |
| 720 | 728 | cell = table [row++]; |
|---|
| 721 | 729 | else |
|---|
| 722 | | return false; |
|---|
| | 730 | return null; |
|---|
| 723 | 731 | |
|---|
| 724 | 732 | prior = cell; |
|---|
| 725 | | v = cell.value; |
|---|
| 726 | 733 | cell = cell.next; |
|---|
| 727 | | return true; |
|---|
| | 734 | return &prior.value; |
|---|
| 728 | 735 | } |
|---|
| 729 | 736 | |
|---|
| 730 | | void remove () |
|---|
| | 737 | /*************************************************************** |
|---|
| | 738 | |
|---|
| | 739 | Foreach support |
|---|
| | 740 | |
|---|
| | 741 | ***************************************************************/ |
|---|
| | 742 | |
|---|
| | 743 | int opApply (int delegate(ref V value) dg) |
|---|
| | 744 | { |
|---|
| | 745 | int result; |
|---|
| | 746 | |
|---|
| | 747 | auto c = cell; |
|---|
| | 748 | loop: while (true) |
|---|
| | 749 | { |
|---|
| | 750 | while (c is null) |
|---|
| | 751 | if (row < table.length) |
|---|
| | 752 | c = table [row++]; |
|---|
| | 753 | else |
|---|
| | 754 | break loop; |
|---|
| | 755 | |
|---|
| | 756 | prior = c; |
|---|
| | 757 | c = c.next; |
|---|
| | 758 | if ((result = dg(prior.value)) != 0) |
|---|
| | 759 | break loop; |
|---|
| | 760 | } |
|---|
| | 761 | |
|---|
| | 762 | cell = c; |
|---|
| | 763 | return result; |
|---|
| | 764 | } |
|---|
| | 765 | |
|---|
| | 766 | /*************************************************************** |
|---|
| | 767 | |
|---|
| | 768 | Remove value at the current iterator location |
|---|
| | 769 | |
|---|
| | 770 | ***************************************************************/ |
|---|
| | 771 | |
|---|
| | 772 | bool remove () |
|---|
| 731 | 773 | { |
|---|
| 732 | 774 | if (prior) |
|---|
| 733 | 775 | if (owner.remove (prior, row-1)) |
|---|
| 734 | | // ignore this change |
|---|
| 735 | | ++mutation; |
|---|
| | 776 | { |
|---|
| | 777 | // ignore this change |
|---|
| | 778 | ++mutation; |
|---|
| | 779 | return true; |
|---|
| | 780 | } |
|---|
| | 781 | |
|---|
| 736 | 782 | prior = null; |
|---|
| 737 | | } |
|---|
| 738 | | |
|---|
| 739 | | bool valid () |
|---|
| 740 | | { |
|---|
| 741 | | return owner.mutation is mutation; |
|---|
| 742 | | } |
|---|
| 743 | | |
|---|
| 744 | | Freach freach() |
|---|
| 745 | | { |
|---|
| 746 | | Freach f = {&next}; |
|---|
| 747 | | return f; |
|---|
| | 783 | return false; |
|---|
| 748 | 784 | } |
|---|
| 749 | 785 | } |
|---|
| … | … | |
| 775 | 811 | |
|---|
| 776 | 812 | // explicit generic iteration |
|---|
| 777 | | foreach (value; set.iterator.freach) |
|---|
| | 813 | foreach (value; set.iterator) |
|---|
| 778 | 814 | Stdout (value).newline; |
|---|
| 779 | 815 | |
|---|
| 780 | 816 | // generic iteration with optional remove |
|---|
| 781 | 817 | auto s = set.iterator; |
|---|
| 782 | | foreach (value; s.freach) |
|---|
| | 818 | foreach (value; s) |
|---|
| 783 | 819 | {} // s.remove; |
|---|
| 784 | 820 | |
|---|
| r3964 |
r3966 |
|
| 29 | 29 | --- |
|---|
| 30 | 30 | Iterator iterator () |
|---|
| 31 | | IteratorMatch iterator (V value) |
|---|
| 32 | 31 | int opApply (int delegate(ref V value) dg) |
|---|
| 33 | 32 | |
|---|
| … | … | |
| 907 | 906 | /*********************************************************************** |
|---|
| 908 | 907 | |
|---|
| 909 | | Iterator with no filtering |
|---|
| | 908 | List iterator |
|---|
| 910 | 909 | |
|---|
| 911 | 910 | ***********************************************************************/ |
|---|
| … | … | |
| 919 | 918 | uint mutation; |
|---|
| 920 | 919 | |
|---|
| | 920 | /*************************************************************** |
|---|
| | 921 | |
|---|
| | 922 | Did the container change underneath us? |
|---|
| | 923 | |
|---|
| | 924 | ***************************************************************/ |
|---|
| | 925 | |
|---|
| 921 | 926 | bool valid () |
|---|
| 922 | 927 | { |
|---|
| 923 | 928 | return owner.mutation is mutation; |
|---|
| 924 | 929 | } |
|---|
| | 930 | |
|---|
| | 931 | /*************************************************************** |
|---|
| | 932 | |
|---|
| | 933 | Accesses the next value, and returns false when |
|---|
| | 934 | there are no further values to traverse |
|---|
| | 935 | |
|---|
| | 936 | ***************************************************************/ |
|---|
| 925 | 937 | |
|---|
| 926 | 938 | bool next (ref V v) |
|---|
| … | … | |
| 930 | 942 | } |
|---|
| 931 | 943 | |
|---|
| | 944 | /*************************************************************** |
|---|
| | 945 | |
|---|
| | 946 | Return a pointer to the next value, or null when |
|---|
| | 947 | there are no further values to traverse |
|---|
| | 948 | |
|---|
| | 949 | ***************************************************************/ |
|---|
| | 950 | |
|---|
| 932 | 951 | V* next () |
|---|
| 933 | 952 | { |
|---|
| … | … | |
| 942 | 961 | } |
|---|
| 943 | 962 | |
|---|
| | 963 | /*************************************************************** |
|---|
| | 964 | |
|---|
| | 965 | Foreach support |
|---|
| | 966 | |
|---|
| | 967 | ***************************************************************/ |
|---|
| | 968 | |
|---|
| 944 | 969 | int opApply (int delegate(ref V value) dg) |
|---|
| 945 | 970 | { |
|---|
| … | … | |
| 950 | 975 | { |
|---|
| 951 | 976 | prior = hook; |
|---|
| | 977 | hook = &n.next; |
|---|
| 952 | 978 | if ((result = dg(n.value)) != 0) |
|---|
| 953 | 979 | break; |
|---|
| 954 | | n = *(hook = &n.next); |
|---|
| | 980 | n = *hook; |
|---|
| 955 | 981 | } |
|---|
| 956 | 982 | node = n; |
|---|
| 957 | 983 | return result; |
|---|
| 958 | 984 | } |
|---|
| | 985 | |
|---|
| | 986 | /*************************************************************** |
|---|
| | 987 | |
|---|
| | 988 | Remove value at the current iterator location |
|---|
| | 989 | |
|---|
| | 990 | ***************************************************************/ |
|---|
| 959 | 991 | |
|---|
| 960 | 992 | bool remove () |
|---|
| … | … | |
| 967 | 999 | hook = prior; |
|---|
| 968 | 1000 | prior = null; |
|---|
| | 1001 | |
|---|
| 969 | 1002 | // ignore this change |
|---|
| 970 | 1003 | ++mutation; |
|---|
|