summaryrefslogtreecommitdiffstats
path: root/tools/gn/deps_iterator.h
blob: 1c3a75e141747c3faa5e86bb0e3f8db5255853a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_GN_DEPS_ITERATOR_H_
#define TOOLS_GN_DEPS_ITERATOR_H_

#include "base/basictypes.h"
#include "tools/gn/label_ptr.h"

class Target;

// Provides an iterator for iterating over multiple LabelTargetVectors to
// make it convenient to iterate over all deps of a target.
//
// This works by maintaining a simple stack of vectors (since we have a fixed
// number of deps types). When the stack is empty, we've reached the end. This
// means that the default-constructed iterator == end() for any sequence.
class DepsIterator {
 public:
  // Creates an empty iterator.
  DepsIterator();

  // Iterate over the deps in the given vectors. If passing less than three,
  // pad with nulls.
  DepsIterator(const LabelTargetVector* a,
               const LabelTargetVector* b,
               const LabelTargetVector* c);

  // Prefix increment operator. This assumes there are more items (i.e.
  // *this != DepsIterator()).
  //
  // For internal use, this function tolerates an initial index equal to the
  // length of the current vector. In this case, it will advance to the next
  // one.
  DepsIterator& operator++();

  // Comparison for STL-based loops.
  bool operator!=(const DepsIterator& other) {
    return current_index_ != other.current_index_ ||
        vect_stack_[0] != other.vect_stack_[0] ||
        vect_stack_[1] != other.vect_stack_[1] ||
        vect_stack_[2] != other.vect_stack_[2];
  }

  // Dereference operator for STL-compatible iterators.
  const LabelTargetPair& operator*() const {
    DCHECK_LT(current_index_, vect_stack_[0]->size());
    return (*vect_stack_[0])[current_index_];
  }

 private:
  const LabelTargetVector* vect_stack_[3];

  size_t current_index_;
};

// Provides a virtual container implementing begin() and end() for a
// sequence of deps. This can then be used in range-based for loops.
class DepsIteratorRange {
 public:
  explicit DepsIteratorRange(const DepsIterator& b);
  ~DepsIteratorRange();

  const DepsIterator& begin() const { return begin_; }
  const DepsIterator& end() const { return end_; }

 private:
  DepsIterator begin_;
  DepsIterator end_;
};

#endif  // TOOLS_GN_DEPS_ITERATOR_H_