| // 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 <stddef.h> | 
 |  | 
 | #include "tools/gn/label_ptr.h" | 
 |  | 
 | // 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) const { | 
 |     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_ |