| 24 | { } |
| 25 | |
| 26 | void DeepIterator::next() { |
| 27 | if (!_value) |
| 28 | return; |
| 29 | |
| 30 | if (_skipChildren) |
| 31 | _skipChildren = false; |
| 32 | else if (_path.empty()) |
| 33 | iterateContainer(_value); |
| 34 | else |
| 35 | queueChildren(); |
| 36 | |
| 37 | if (!_path.empty()) |
| 38 | _path.pop_back(); |
| 39 | |
| 40 | do { |
| 41 | if (_arrayIt) { |
| 42 | // Next array item: |
| 43 | _value = (*_arrayIt).value(); |
| 44 | if (_value) { |
| 45 | _path.push_back({nullslice, _arrayIndex++}); |
| 46 | ++(*_arrayIt); |
| 47 | } else { |
| 48 | _arrayIt.reset(); |
| 49 | } |
| 50 | } else if (_dictIt) { |
| 51 | // Next dict item: |
| 52 | _value = (*_dictIt).value(); |
| 53 | if (_value) { |
| 54 | _path.push_back({(*_dictIt).keyString(), 0}); |
| 55 | ++(*_dictIt); |
| 56 | } else { |
| 57 | if (!_sk) |
| 58 | _sk = _dictIt->sharedKeys(); |
| 59 | _dictIt.reset(); |
| 60 | } |
| 61 | } else { |
| 62 | // End of array/dict, so start another one: |
| 63 | _value = nullptr; |
| 64 | if (_stack.empty()) |
| 65 | return; // end of iteration |
| 66 | while (_stack.front().second == nullptr) { |
| 67 | // end of a level of hierarchy; pop the path, or stop if it's empty: |
| 68 | if (_path.empty()) |
| 69 | return; // end of iteration |
| 70 | _path.pop_back(); |
| 71 | _stack.pop_front(); |
| 72 | } |
| 73 | |
| 74 | // Pop the next container and its key from the stack: |
| 75 | auto container = _stack.front().second; |
| 76 | _path.push_back(_stack.front().first); |
| 77 | _stack.pop_front(); |
| 78 | iterateContainer(container); |
| 79 | } |
| 80 | } while (!_value); |
| 81 | } |
| 82 | |
| 83 | bool DeepIterator::iterateContainer(const Value *container) { |
nothing calls this directly
no test coverage detected