@@ -97,6 +97,8 @@ struct TTree(T, bool allowDuplicates = false, alias less = "a < b",
9797 return retVal;
9898 }
9999
100+ alias put = insert;
101+
100102 /**
101103 * Removes a value from the tree.
102104 * Params:
@@ -233,27 +235,72 @@ struct TTree(T, bool allowDuplicates = false, alias less = "a < b",
233235 current = current.left;
234236 }
235237
238+ void currentToLeastContaining (inout T val)
239+ {
240+ if (current is null )
241+ return ;
242+ while (current ! is null )
243+ {
244+ assert (current.registry != 0 );
245+ auto first = current.values [0 ];
246+ auto last = current.values [current.nextAvailableIndex - 1 ];
247+ immutable bool valLessFirst = _less(val, first);
248+ immutable bool valLessLast = _less(val, last);
249+ immutable bool firstLessVal = _less(first, val);
250+ immutable bool lastLessVal = _less(last, val);
251+ if (firstLessVal && valLessLast)
252+ return ;
253+ else if (valLessFirst)
254+ current = current.left;
255+ else if (lastLessVal)
256+ current = current.right;
257+ else
258+ {
259+ static if (allowDuplicates)
260+ {
261+ if (! valLessFirst && ! firstLessVal)
262+ {
263+ auto c = current;
264+ current = current.left;
265+ currentToLeastContaining(val);
266+ if (current is null )
267+ current = c;
268+ return ;
269+ }
270+ else
271+ return ;
272+ }
273+ else
274+ return ;
275+ }
276+
277+ }
278+ }
279+
236280 this (inout (Node)* n, RangeType type, inout T val)
237281 {
238282 current = n;
239283 this .type = type;
240284 this .val = val;
241- currentToLeftmost();
242285 with (RangeType) final switch (type)
243286 {
244287 case all:
288+ currentToLeftmost();
245289 break ;
246290 case lower:
291+ currentToLeftmost();
247292 if (_less(val, front()))
248293 current = null ;
249294 break ;
250295 case equal:
296+ currentToLeastContaining(val);
251297 while (current ! is null && _less(front(), val))
252298 _popFront();
253299 if (current is null || _less(front(), val) || _less(val, front()))
254300 current = null ;
255301 break ;
256302 case upper:
303+ currentToLeastContaining(val);
257304 while (current ! is null && ! _less(val, front()))
258305 _popFront();
259306 break ;
@@ -798,7 +845,7 @@ private:
798845unittest
799846{
800847 import core.memory : GC ;
801- import std.algorithm : equal, sort, map, filter;
848+ import std.algorithm : equal, sort, map, filter, each ;
802849 import std.array : array;
803850 import std.range : iota, walkLength, isInputRange;
804851 import std.string : format;
@@ -905,9 +952,10 @@ unittest
905952 assert (strings.insert(" d" ));
906953 assert (strings.insert(" d" ));
907954 assert (strings.length == 5 );
908- assert (equal(strings.equalRange(" d" ), [" d" , " d" ]));
909- assert (equal(strings.lowerBound(" d" ), [" a" , " b" , " c" ]));
910- assert (equal(strings.upperBound(" c" ), [" d" , " d" ]));
955+ assert (equal(strings.equalRange(" d" ), [" d" , " d" ]), format(" %s" , strings.equalRange(" d" )));
956+ assert (equal(strings.equalRange(" a" ), [" a" ]), format(" %s" , strings.equalRange(" a" )));
957+ assert (equal(strings.lowerBound(" d" ), [" a" , " b" , " c" ]), format(" %s" , strings.lowerBound(" d" )));
958+ assert (equal(strings.upperBound(" c" ), [" d" , " d" ]), format(" %s" , strings.upperBound(" c" )));
911959 }
912960
913961 {
@@ -1026,4 +1074,24 @@ unittest
10261074 assert (tree.equalRange(ABC (15 )).walkLength() == 4 ,
10271075 format(" Actual length = %d" , tree.equalRange(ABC (15 )).walkLength()));
10281076 }
1077+
1078+ {
1079+ TTree! int ints2;
1080+ iota(0 , 1_000_000).each! (a => ints2.insert(a));
1081+ assert (equal(iota(0 , 1_000_000), ints2[]));
1082+ assert (ints2.length == 1_000_000);
1083+ foreach (i; 0 .. 1_000_000)
1084+ assert (! ints2.equalRange(i).empty, format(" Could not find %d" , i));
1085+ }
1086+
1087+ {
1088+ TTree! int ints3;
1089+ foreach (i; iota(0 , 1_000_000).filter! (a => a % 2 == 0 ))
1090+ ints3.insert(i);
1091+ assert (ints3.length == 500_000);
1092+ foreach (i; iota(0 , 1_000_000).filter! (a => a % 2 == 0 ))
1093+ assert (! ints3.equalRange(i).empty);
1094+ foreach (i; iota(0 , 1_000_000).filter! (a => a % 2 == 1 ))
1095+ assert (ints3.equalRange(i).empty);
1096+ }
10291097}
0 commit comments