| // 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 "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_ |