LCOV - code coverage report
Current view: top level - _classes/controller - iterator_controller.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 60 56.7 %
Date: 2024-10-04 11:08:31 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           4 :   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           1 :   IteratorController(this.data, {required this.transform, this.boundary, this.filter});
      31             : 
      32           0 :   @override
      33           0 :   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           1 :   @override
      45           4 :   bool get isFinished => keys.length == pointer;
      46             : 
      47           1 :   @override
      48             :   void jumpTo(T key) {
      49           2 :     final nextKey = data.firstKeyAfter(key);
      50           3 :     pointer = nextKey != null ? keys.indexOf(nextKey) : keys.length - 1;
      51             :   }
      52             : 
      53           1 :   @override
      54             :   Iterable<M?> loop() sync* {
      55           4 :     while (pointer < keys.length) {
      56           4 :       final index = keys.elementAt(pointer++);
      57           3 :       if (boundary != null && boundary! < index) {
      58             :         break;
      59             :       }
      60           4 :       M? value = transform(data[index] ?? '');
      61           3 :       if (filter?.call(value) == true) {
      62             :         continue;
      63             :       }
      64             :       yield value;
      65             :     }
      66             :   }
      67             : 
      68           1 :   @override
      69             :   M? get next {
      70           2 :     final iterator = loop().iterator;
      71           2 :     return iterator.moveNext() ? iterator.current as M : null;
      72             :   }
      73             : 
      74           1 :   @override
      75             :   List<M> chunk(int length) {
      76           3 :     final result = List.generate(length, (_) => next);
      77           2 :     result.removeWhere((e) => e == null);
      78           1 :     return result.cast<M>();
      79             :   }
      80             : 
      81           0 :   @override
      82           0 :   List<M> toList() => [...loop()].cast();
      83             : 
      84           0 :   @override
      85             :   List<M> getTill(T boundary) {
      86           0 :     final result = <M>[];
      87           0 :     while (!isFinished && boundary > keys[pointer]) {
      88           0 :       final value = next;
      89           0 :       if (boundary <= keys[pointer - 1]) {
      90           0 :         pointer--;
      91             :         break;
      92             :       }
      93             :       if (value == null) {
      94             :         break;
      95             :       }
      96           0 :       result.add(value);
      97             :     }
      98             :     return result;
      99             :   }
     100             : }
     101             : 
     102             : class IteratorReverseController<T extends num, K, M> extends IteratorController<T, K, M> {
     103           1 :   IteratorReverseController(super.data, {required super.transform, super.boundary, super.filter}) {
     104           5 :     pointer = data.keys.length - 1;
     105           2 :     _pointer = pointer;
     106             :   }
     107             : 
     108           1 :   @override
     109           2 :   bool get isFinished => pointer < 0;
     110             : 
     111           0 :   @override
     112           0 :   void reset() => data.keys.length - 1;
     113             : 
     114           1 :   @override
     115             :   void jumpTo(T key) {
     116           2 :     final nextKey = data.lastKeyBefore(key);
     117           3 :     pointer = nextKey != null ? keys.indexOf(nextKey) : 0;
     118             :   }
     119             : 
     120           1 :   @override
     121             :   Iterable<M?> loop() sync* {
     122           2 :     while (pointer >= 0) {
     123           4 :       final index = keys.elementAt(pointer--);
     124           3 :       if (boundary != null && boundary! > index) {
     125             :         break;
     126             :       }
     127           4 :       M? value = transform(data[index] ?? '');
     128           2 :       if (filter?.call(value) == true) {
     129             :         continue;
     130             :       }
     131             :       yield value;
     132             :     }
     133             :   }
     134             : 
     135           0 :   @override
     136             :   List<M> getTill(T boundary) {
     137           0 :     final result = <M>[];
     138           0 :     while (!isFinished && boundary < keys[pointer]) {
     139           0 :       final value = next;
     140           0 :       if (boundary >= keys[pointer + 1]) {
     141           0 :         pointer++;
     142             :         break;
     143             :       }
     144             :       if (value == null) {
     145             :         break;
     146             :       }
     147           0 :       result.add(value);
     148             :     }
     149             :     return result;
     150             :   }
     151             : }

Generated by: LCOV version 1.14