Index: src/compiler/generic-node.h |
diff --git a/src/compiler/generic-node.h b/src/compiler/generic-node.h |
index 506a34fc1323d4250a5b6e2c841f626111b98677..34b7ac1a7fce98294cacd02999508b62aba42420 100644 |
--- a/src/compiler/generic-node.h |
+++ b/src/compiler/generic-node.h |
@@ -14,6 +14,8 @@ namespace internal { |
namespace compiler { |
class GenericGraphBase; |
+template <class N> |
+class GenericEdge; |
typedef int NodeId; |
@@ -59,11 +61,25 @@ class GenericNode : public B { |
inline void TrimInputCount(int input_count); |
+ class InputEdges { |
+ public: |
+ class iterator; |
+ iterator begin(); |
+ iterator end(); |
+ bool empty() { return begin() == end(); } |
+ |
+ explicit InputEdges(GenericNode* node) : node_(node) {} |
+ |
+ private: |
+ GenericNode* node_; |
+ }; |
+ |
class Inputs { |
public: |
class iterator; |
iterator begin(); |
iterator end(); |
+ bool empty() { return begin() == end(); } |
explicit Inputs(GenericNode* node) : node_(node) {} |
@@ -71,8 +87,22 @@ class GenericNode : public B { |
GenericNode* node_; |
}; |
+ InputEdges input_edges() { return InputEdges(this); } |
Inputs inputs() { return Inputs(this); } |
+ class UseEdges { |
+ public: |
+ class iterator; |
+ iterator begin(); |
+ iterator end(); |
+ bool empty() { return begin() == end(); } |
+ |
+ explicit UseEdges(GenericNode* node) : node_(node) {} |
+ |
+ private: |
+ GenericNode* node_; |
+ }; |
+ |
class Uses { |
public: |
class iterator; |
@@ -87,8 +117,7 @@ class GenericNode : public B { |
}; |
Uses uses() { return Uses(this); } |
- |
- class Edge; |
+ UseEdges use_edges() { return UseEdges(this); } |
bool OwnedBy(GenericNode* owner) const; |
@@ -97,6 +126,7 @@ class GenericNode : public B { |
protected: |
friend class GenericGraphBase; |
+ friend class GenericEdge<S>; |
class Use : public ZoneObject { |
public: |
@@ -162,115 +192,200 @@ class GenericNode : public B { |
// An encapsulation for information associated with a single use of node as a |
// input from another node, allowing access to both the defining node and |
-// the ndoe having the input. |
-template <class B, class S> |
-class GenericNode<B, S>::Edge { |
+// the node having the input. |
+template <class N> |
+class GenericEdge { |
public: |
- S* from() const { return static_cast<S*>(input_->use->from); } |
- S* to() const { return static_cast<S*>(input_->to); } |
+ GenericEdge(const GenericEdge& other) : input_(other.input_) {} |
+ GenericEdge() : input_(NULL) {} |
+ |
+ N* from() const { return static_cast<N*>(input_->use->from); } |
+ N* to() const { return static_cast<N*>(input_->to); } |
int index() const { |
int index = input_->use->input_index; |
DCHECK(index < input_->use->from->input_count_); |
return index; |
} |
+ bool operator==(const GenericEdge& other) { return input_ == other.input_; } |
+ bool operator!=(const GenericEdge& other) { return !(*this == other); } |
- private: |
- friend class GenericNode<B, S>::Uses::iterator; |
- friend class GenericNode<B, S>::Inputs::iterator; |
+ explicit GenericEdge(typename N::Input* input) : input_(input) {} |
- explicit Edge(typename GenericNode<B, S>::Input* input) : input_(input) {} |
+ void UpdateTo(N* new_to) { input_->Update(new_to); } |
- typename GenericNode<B, S>::Input* input_; |
+ private: |
+ typename N::Input* input_; |
}; |
+ |
// A forward iterator to visit the nodes which are depended upon by a node |
// in the order of input. |
template <class B, class S> |
-class GenericNode<B, S>::Inputs::iterator { |
+class GenericNode<B, S>::InputEdges::iterator { |
public: |
- iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT |
- : node_(other.node_), |
- index_(other.index_) {} |
+ typedef std::forward_iterator_tag iterator_category; |
+ typedef int difference_type; |
+ typedef GenericEdge<S> value_type; |
+ typedef GenericEdge<S>* pointer; |
+ typedef GenericEdge<S>& reference; |
+ iterator( |
+ const typename GenericNode<B, S>::InputEdges::iterator& other) // NOLINT |
+ : input_(other.input_) {} |
+ iterator() : input_(NULL) {} |
+ |
+ GenericEdge<S> operator*() const { return GenericEdge<S>(input_); } |
+ bool operator==(const iterator& other) const { return Equals(other); } |
+ bool operator!=(const iterator& other) const { return !Equals(other); } |
+ iterator& operator++() { |
+ DCHECK(input_ != NULL); |
+ GenericEdge<S> edge(input_); |
+ GenericNode<B, S>* from = edge.from(); |
+ SetInput(from, input_->use->input_index + 1); |
+ return *this; |
+ } |
+ iterator& operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
+ } |
- S* operator*() { return static_cast<S*>(GetInput()->to); } |
- typename GenericNode<B, S>::Edge edge() { |
- return typename GenericNode::Edge(GetInput()); |
+ private: |
+ friend class GenericNode; |
+ |
+ iterator(GenericNode* from, int index = 0) : input_(NULL) { |
+ SetInput(from, index); |
} |
- bool operator==(const iterator& other) const { |
- return other.index_ == index_ && other.node_ == node_; |
+ |
+ bool Equals(const iterator& other) const { return other.input_ == input_; } |
+ void SetInput(GenericNode* from, int index) { |
+ DCHECK(index >= 0 && index <= from->InputCount()); |
+ if (index < from->InputCount()) { |
+ input_ = from->GetInputRecordPtr(index); |
+ } else { |
+ input_ = NULL; |
+ } |
} |
- bool operator!=(const iterator& other) const { return !(other == *this); } |
+ |
+ Input* input_; |
+}; |
+ |
+ |
+template <class B, class S> |
+class GenericNode<B, S>::Inputs::iterator { |
+ public: |
+ typedef std::forward_iterator_tag iterator_category; |
+ typedef int difference_type; |
+ typedef S value_type; |
+ typedef S* pointer; |
+ typedef S& reference; |
+ iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT |
+ : iter_(other.iter_) {} |
+ iterator() {} |
+ |
+ S* operator*() const { return (*iter_).to(); } |
+ bool operator==(const iterator& other) const { return Equals(other); } |
+ bool operator!=(const iterator& other) const { return !Equals(other); } |
iterator& operator++() { |
- DCHECK(node_ != NULL); |
- DCHECK(index_ < node_->input_count_); |
- ++index_; |
+ ++iter_; |
return *this; |
} |
- iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) { |
- typename GenericNode<B, S>::Input* input = GetInput(); |
- input->Update(new_to); |
- index_++; |
- return *this; |
+ iterator& operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
} |
- int index() { return index_; } |
private: |
- friend class GenericNode; |
+ friend class GenericNode<B, S>::Inputs; |
- explicit iterator(GenericNode* node, int index) |
- : node_(node), index_(index) {} |
+ iterator(GenericNode* from, int index = 0) : iter_(from, index) {} |
- Input* GetInput() const { return node_->GetInputRecordPtr(index_); } |
+ bool Equals(const iterator& other) const { return other.iter_ == iter_; } |
- GenericNode* node_; |
- int index_; |
+ typename GenericNode<B, S>::InputEdges::iterator iter_; |
}; |
+ |
// A forward iterator to visit the uses of a node. The uses are returned in |
// the order in which they were added as inputs. |
template <class B, class S> |
-class GenericNode<B, S>::Uses::iterator { |
+class GenericNode<B, S>::UseEdges::iterator { |
public: |
- iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT |
+ iterator( |
+ const typename GenericNode<B, S>::UseEdges::iterator& other) // NOLINT |
: current_(other.current_), |
+ next_(other.next_), |
index_(other.index_) {} |
- S* operator*() { return static_cast<S*>(current_->from); } |
- typename GenericNode<B, S>::Edge edge() { |
- return typename GenericNode::Edge(CurrentInput()); |
- } |
+ GenericEdge<S> operator*() const { return GenericEdge<S>(CurrentInput()); } |
- bool operator==(const iterator& other) { return other.current_ == current_; } |
- bool operator!=(const iterator& other) { return other.current_ != current_; } |
+ bool operator==(const iterator& other) { return Equals(other); } |
+ bool operator!=(const iterator& other) { return !Equals(other); } |
iterator& operator++() { |
DCHECK(current_ != NULL); |
index_++; |
- current_ = current_->next; |
+ current_ = next_; |
+ next_ = (current_ == NULL) ? NULL : current_->next; |
return *this; |
} |
- iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) { |
+ iterator& operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
+ } |
+ |
+ private: |
+ friend class GenericNode<B, S>::UseEdges; |
+ |
+ iterator() : current_(NULL), next_(NULL), index_(0) {} |
+ explicit iterator(GenericNode<B, S>* node) |
+ : current_(node->first_use_), |
+ next_(current_ == NULL ? NULL : current_->next), |
+ index_(0) {} |
+ |
+ bool Equals(const iterator& other) const { |
+ return other.current_ == current_; |
+ } |
+ |
+ Input* CurrentInput() const { |
+ return current_->from->GetInputRecordPtr(current_->input_index); |
+ } |
+ |
+ typename GenericNode<B, S>::Use* current_; |
+ typename GenericNode<B, S>::Use* next_; |
+ int index_; |
+}; |
+ |
+ |
+// A forward iterator to visit the uses edges of a node. The edges are returned |
+// in the order in which they were added as inputs. |
+template <class B, class S> |
+class GenericNode<B, S>::Uses::iterator { |
+ public: |
+ iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT |
+ : current_(other.current_) {} |
+ |
+ S* operator*() { return static_cast<S*>(current_->from); } |
+ |
+ bool operator==(const iterator& other) { return other.current_ == current_; } |
+ bool operator!=(const iterator& other) { return other.current_ != current_; } |
+ iterator& operator++() { |
DCHECK(current_ != NULL); |
- index_++; |
- typename GenericNode<B, S>::Input* input = CurrentInput(); |
current_ = current_->next; |
- input->Update(new_to); |
return *this; |
} |
- int index() const { return index_; } |
private: |
friend class GenericNode<B, S>::Uses; |
- iterator() : current_(NULL), index_(0) {} |
- explicit iterator(GenericNode<B, S>* node) |
- : current_(node->first_use_), index_(0) {} |
+ iterator() : current_(NULL) {} |
+ explicit iterator(GenericNode<B, S>* node) : current_(node->first_use_) {} |
Input* CurrentInput() const { |
return current_->from->GetInputRecordPtr(current_->input_index); |
} |
typename GenericNode<B, S>::Use* current_; |
- int index_; |
}; |
} |
} |