LCOV - code coverage report
Current view: top level - lib/_classes/controller - iterator_controller.dart Coverage Total Hit
Test: lcov.info Lines: 10.0 % 60 6
Test Date: 2026-11-14 15:04:37 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2023 The terCAD team. All rights reserved.
       2              : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3              : 
       4              : import 'dart:collection';
       5              : 
       6              : abstract interface class InterfaceIterator<T extends num, K, M> {
       7              :   void reset();
       8              :   int get length;
       9              :   bool get isFirst;
      10              :   bool get isFinished;
      11              :   bool get isEmpty;
      12              :   M? get next;
      13              :   void jumpTo(T key);
      14              :   Iterable<M?> loop();
      15              :   List<M> chunk(int length);
      16              :   List<M> getTill(T boundary);
      17              :   List<M> toList();
      18              : }
      19              : 
      20              : class IteratorController<T extends num, K, M> implements InterfaceIterator<T, K, M> {
      21              :   SplayTreeMap<T, K> data;
      22              :   T? boundary;
      23              :   Function? filter;
      24              :   late List<T> keys = data.keys.toList();
      25              :   int pointer = 0;
      26              :   // ignore: prefer_final_fields
      27              :   int _pointer = 0;
      28              :   Function transform;
      29              : 
      30            6 :   IteratorController(this.data, {required this.transform, this.boundary, this.filter});
      31              : 
      32            1 :   @override
      33            2 :   int get length => data.length;
      34              : 
      35            0 :   @override
      36            0 :   void reset() => pointer = 0;
      37              : 
      38            0 :   @override
      39            0 :   bool get isEmpty => data.isEmpty;
      40              : 
      41            0 :   @override
      42            0 :   bool get isFirst => _pointer == pointer;
      43              : 
      44            0 :   @override
      45            0 :   bool get isFinished => keys.length == pointer;
      46              : 
      47            0 :   @override
      48              :   void jumpTo(T key) {
      49            0 :     final nextKey = data.firstKeyAfter(key);
      50            0 :     pointer = nextKey != null ? keys.indexOf(nextKey) : keys.length - 1;
      51              :   }
      52              : 
      53            0 :   @override
      54              :   Iterable<M?> loop() sync* {
      55            0 :     while (pointer < keys.length) {
      56            0 :       final index = keys.elementAt(pointer++);
      57            0 :       if (boundary != null && boundary! < index) {
      58              :         break;
      59              :       }
      60            0 :       M? value = transform(data[index] ?? '');
      61            0 :       if (filter?.call(value) == true) {
      62              :         continue;
      63              :       }
      64              :       yield value;
      65              :     }
      66              :   }
      67              : 
      68            0 :   @override
      69              :   M? get next {
      70            0 :     final iterator = loop().iterator;
      71            0 :     return iterator.moveNext() ? iterator.current as M : null;
      72              :   }
      73              : 
      74            0 :   @override
      75              :   List<M> chunk(int length) {
      76            0 :     final result = List.generate(length, (_) => next);
      77            0 :     result.removeWhere((e) => e == null);
      78            0 :     if (result.isEmpty) return [];
      79            0 :     return result.cast<M>();
      80              :   }
      81              : 
      82            0 :   @override
      83            0 :   List<M> toList() => [...loop()].cast();
      84              : 
      85            0 :   @override
      86              :   List<M> getTill(T boundary) {
      87            0 :     final result = <M>[];
      88            0 :     while (!isFinished && boundary > keys[pointer]) {
      89            0 :       final value = next;
      90            0 :       if (boundary <= keys[pointer - 1]) {
      91            0 :         pointer--;
      92              :         break;
      93              :       }
      94              :       if (value == null) {
      95              :         break;
      96              :       }
      97            0 :       result.add(value);
      98              :     }
      99              :     return result;
     100              :   }
     101              : }
     102              : 
     103              : class IteratorReverseController<T extends num, K, M> extends IteratorController<T, K, M> {
     104            6 :   IteratorReverseController(super.data, {required super.transform, super.boundary, super.filter}) {
     105           30 :     pointer = data.keys.length - 1;
     106           12 :     _pointer = pointer;
     107              :   }
     108              : 
     109            0 :   @override
     110            0 :   bool get isFinished => pointer < 0;
     111              : 
     112            0 :   @override
     113            0 :   void reset() => data.keys.length - 1;
     114              : 
     115            0 :   @override
     116              :   void jumpTo(T key) {
     117            0 :     final nextKey = data.lastKeyBefore(key);
     118            0 :     pointer = nextKey != null ? keys.indexOf(nextKey) : 0;
     119              :   }
     120              : 
     121            0 :   @override
     122              :   Iterable<M?> loop() sync* {
     123            0 :     while (pointer >= 0) {
     124            0 :       final index = keys.elementAt(pointer--);
     125            0 :       if (boundary != null && boundary! > index) {
     126              :         break;
     127              :       }
     128            0 :       M? value = transform(data[index] ?? '');
     129            0 :       if (filter?.call(value) == true) {
     130              :         continue;
     131              :       }
     132              :       yield value;
     133              :     }
     134              :   }
     135              : 
     136            0 :   @override
     137              :   List<M> getTill(T boundary) {
     138            0 :     final result = <M>[];
     139            0 :     while (!isFinished && boundary < keys[pointer]) {
     140            0 :       final value = next;
     141            0 :       if (boundary >= keys[pointer + 1]) {
     142            0 :         pointer++;
     143              :         break;
     144              :       }
     145              :       if (value == null) {
     146              :         break;
     147              :       }
     148            0 :       result.add(value);
     149              :     }
     150              :     return result;
     151              :   }
     152              : }
        

Generated by: LCOV version 2.0-1