/*
* This file is part of the Trickl Open Source Libraries.
*
* Trickl Open Source Libraries - http://open.trickl.com/
*
* Copyright (C) 2007 Aaron Windsor (part of the C++ Boost Graph Library)
* Copyright (C) 2011 Tim Gee.
*
* Trickl Open Source Libraries are free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Trickl Open Source Libraries are distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this project. If not, see <http://www.gnu.org/licenses/>.
*/
package com.trickl.graph.planar;
import java.util.List;
import java.util.LinkedList;
import java.util.Collections;
import java.util.Map;
import java.util.Iterator;
import org.jgrapht.Graph;
public class FaceHandle<V, E> {
public interface OldHandlesStoragePolicy<V, E> {
void initializeOldVertices();
void storeOldFaceHandles(V firstVertex,
V secondVertex,
E firstEdge,
E secondEdge);
V getFirstVertex();
V getSecondVertex();
E getFirstEdge();
E getSecondEdge();
};
public static class StoreOldHandles<V, E> implements OldHandlesStoragePolicy<V, E> {
private V firstVertex;
private V secondVertex;
private E firstEdge;
private E secondEdge;
public void initializeOldVertices() {
firstVertex = null;
secondVertex = null;
}
public void storeOldFaceHandles(V firstVertex,
V secondVertex,
E firstEdge,
E secondEdge) {
this.firstVertex = firstVertex;
this.secondVertex = secondVertex;
this.firstEdge = firstEdge;
this.secondEdge = secondEdge;
}
public V getFirstVertex() {
return firstVertex;
}
public V getSecondVertex() {
return secondVertex;
}
public E getFirstEdge() {
return firstEdge;
}
public E getSecondEdge() {
return secondEdge;
}
};
public static class NoOldHandles<V, E> implements OldHandlesStoragePolicy<V, E> {
public void initializeOldVertices() {
}
public void storeOldFaceHandles(V firstVertex,
V secondVertex,
E firstEdge,
E secondEdge) {
}
public V getFirstVertex() {
throw new UnsupportedOperationException("Using a storage policy that does not store handles.");
}
public V getSecondVertex() {
throw new UnsupportedOperationException("Using a storage policy that does not store handles.");
}
public E getFirstEdge() {
throw new UnsupportedOperationException("Using a storage policy that does not store handles.");
}
public E getSecondEdge() {
throw new UnsupportedOperationException("Using a storage policy that does not store handles.");
}
};
public interface EmbeddingStoragePolicy<E> {
void addLast(E edge);
void addFront(E edge);
void reverse();
void addFront(EmbeddingStoragePolicy<E> policy);
void addLast(EmbeddingStoragePolicy<E> policy);
void getList(List<E> out);
};
public static class NoEmbedding<E> implements EmbeddingStoragePolicy<E> {
public void addLast(E edge) {
}
public void addFront(E edge) {
}
public void reverse() {
}
public void addFront(EmbeddingStoragePolicy<E> policy) {
}
public void addLast(EmbeddingStoragePolicy<E> policy) {
}
public void getList(List<E> out) {
}
};
public static class TreeEmbedding<E> implements EmbeddingStoragePolicy<E> {
public static class Node<E> {
private boolean isReversed = false;
private E data;
private boolean hasData;
private Node<E> left;
private Node<E> right;
public Node(E data) {
this.data = data;
this.hasData = true;
}
public Node(Node<E> left_child, Node<E> right_child) {
hasData = false;
left = left_child;
right = right_child;
}
};
private Node<E> value;
public void addLast(E e) {
value = new Node<E>(value, new Node<E>(e));
}
public void addFront(E e) {
value = new Node<E>(new Node<E>(e), value);
}
public void reverse() {
value.isReversed = !value.isReversed;
}
public void addFront(EmbeddingStoragePolicy<E> other) {
value = new Node<E>(((TreeEmbedding<E>) other).value, value);
}
public void addLast(EmbeddingStoragePolicy<E> other) {
value = new Node<E>(value, ((TreeEmbedding<E>) other).value);
}
public void getList(List<E> out) {
getList(out, value);
}
private void getList(List<E> o_itr,
Node<E> root) {
getList(o_itr, root, false);
}
private void getList(List<E> o_itr,
Node<E> root,
boolean flipped) {
if (root == null) {
return;
}
if (root.hasData) {
o_itr.add(root.data);
}
if ((flipped && !root.isReversed)
|| (!flipped && root.isReversed)) {
getList(o_itr, root.right, true);
getList(o_itr, root.left, true);
} else {
getList(o_itr, root.left, false);
getList(o_itr, root.right, false);
}
}
};
public static class ListEmbedding<E> implements EmbeddingStoragePolicy<E> {
private LinkedList<E> value;
public void addLast(E e) {
value.addLast(e);
}
public void addFront(E e) {
value.addFirst(e);
}
public void reverse() {
Collections.reverse(value);
}
public void addFront(EmbeddingStoragePolicy<E> other) {
value.addAll(0, ((ListEmbedding<E>) other).value);
}
public void addLast(EmbeddingStoragePolicy<E> other) {
value.addAll(((ListEmbedding<E>) other).value);
}
public void getList(List<E> out) {
Collections.copy(value, out);
}
};
protected static class FaceHandleImpl<V, E> {
private V cachedFirstVertex;
private V cachedSecondVertex;
private V trueFirstVertex;
private V trueSecondVertex;
private V anchor;
private E cachedFirstEdge;
private E cachedSecondEdge;
private EmbeddingStoragePolicy<E> embeddingStorage;
private OldHandlesStoragePolicy<V, E> oldHandles;
public FaceHandleImpl(EmbeddingStoragePolicy<E> edge_list,
OldHandlesStoragePolicy<V, E> oldHandles) {
this.embeddingStorage = edge_list;
this.oldHandles = oldHandles;
oldHandles.initializeOldVertices();
}
public void storeOldFaceHandles()
{
oldHandles.storeOldFaceHandles(trueFirstVertex,
trueSecondVertex,
cachedFirstEdge,
cachedSecondEdge);
}
};
private FaceHandleImpl<V, E> impl;
public FaceHandle(EmbeddingStoragePolicy<E> embeddingStorage,
OldHandlesStoragePolicy<V, E> oldHandles,
V anchor) {
impl = new FaceHandleImpl<V, E>(embeddingStorage, oldHandles);
impl.anchor = null;
}
public FaceHandle(EmbeddingStoragePolicy<E> embeddingStorage,
OldHandlesStoragePolicy<V, E> oldHandles) {
impl = new FaceHandleImpl<V, E>(embeddingStorage, oldHandles);
impl.anchor = null;
}
public FaceHandle(EmbeddingStoragePolicy<E> embeddingStorage,
OldHandlesStoragePolicy<V, E> oldHandles,
V anchor,
E initialEdge,
Graph<V, E> graph) {
impl = new FaceHandleImpl<V, E>(embeddingStorage, oldHandles);
impl.anchor = null;
V source = graph.getEdgeSource(initialEdge);
V target = graph.getEdgeTarget(initialEdge);
V otherVertex = source.equals(anchor) ? target : source;
impl.anchor = anchor;
impl.cachedFirstEdge = initialEdge;
impl.cachedSecondEdge = initialEdge;
impl.cachedFirstVertex = otherVertex;
impl.cachedSecondVertex = otherVertex;
impl.trueFirstVertex = otherVertex;
impl.trueSecondVertex = otherVertex;
impl.embeddingStorage.addLast(initialEdge);
impl.oldHandles.storeOldFaceHandles(impl.trueFirstVertex,
impl.trueSecondVertex,
impl.cachedFirstEdge,
impl.cachedSecondEdge);
}
public void storeOldFaceHandles()
{
impl.storeOldFaceHandles();
}
// default copy construction, assignment okay.
public void addFirst(E edge, Graph<V, E> graph) {
impl.embeddingStorage.addFront(edge);
impl.cachedFirstVertex = impl.trueFirstVertex =
graph.getEdgeSource(edge).equals(impl.anchor)
? graph.getEdgeTarget(edge)
: graph.getEdgeSource(edge);
impl.cachedFirstEdge = edge;
}
public void addSecond(E edge, Graph<V, E> graph) {
impl.embeddingStorage.addLast(edge);
impl.cachedSecondVertex = impl.trueSecondVertex =
graph.getEdgeSource(edge).equals(impl.anchor)
? graph.getEdgeTarget(edge)
: graph.getEdgeSource(edge);
impl.cachedSecondEdge = edge;
}
public V getFirstVertex() {
return impl.cachedFirstVertex;
}
public V getSecondVertex() {
return impl.cachedSecondVertex;
}
public V getTrueFirstVertex() {
return impl.trueFirstVertex;
}
public V getTrueSecondVertex() {
return impl.trueSecondVertex;
}
public V getOldFirstVertex() {
return impl.oldHandles.getFirstVertex();
}
public V getOldSecondVertex() {
return impl.oldHandles.getSecondVertex();
}
public E getOldFirstEdge() {
return impl.oldHandles.getFirstEdge();
}
public E getOldSecondEdge() {
return impl.oldHandles.getSecondEdge();
}
public E getFirstEdge() {
return impl.cachedFirstEdge;
}
public E getSecondEdge() {
return impl.cachedSecondEdge;
}
public V getAnchor() {
return impl.anchor;
}
public void glueFirstToSecond(FaceHandle<V, E> bottom) {
impl.embeddingStorage.addFront(bottom.impl.embeddingStorage);
impl.trueFirstVertex = bottom.impl.trueFirstVertex;
impl.cachedFirstVertex = bottom.impl.cachedFirstVertex;
impl.cachedFirstEdge = bottom.impl.cachedFirstEdge;
}
public void glueSecondToFirst(FaceHandle<V, E> bottom) {
impl.embeddingStorage.addLast(bottom.impl.embeddingStorage);
impl.trueSecondVertex = bottom.impl.trueSecondVertex;
impl.cachedSecondVertex = bottom.impl.cachedSecondVertex;
impl.cachedSecondEdge = bottom.impl.cachedSecondEdge;
}
public void flip() {
impl.embeddingStorage.reverse();
V tmpVertex = impl.trueFirstVertex;
impl.trueFirstVertex = impl.trueSecondVertex;
impl.trueSecondVertex = tmpVertex;
tmpVertex = impl.cachedFirstVertex;
impl.cachedFirstVertex = impl.cachedSecondVertex;
impl.cachedSecondVertex = tmpVertex;
E tmpEdge = impl.cachedFirstEdge;
impl.cachedFirstEdge = impl.cachedSecondEdge;
impl.cachedSecondEdge = tmpEdge;
}
public void getList(List<E> o_itr) {
impl.embeddingStorage.getList(o_itr);
}
public void resetVertexCache() {
impl.cachedFirstVertex = impl.trueFirstVertex;
impl.cachedSecondVertex = impl.trueSecondVertex;
}
public void setFirstVertex(V v) {
impl.cachedFirstVertex = v;
}
public void setSecondVertex(V v) {
impl.cachedSecondVertex = v;
}
public static class FaceIterator<V, E> {
// Why TraversalType AND TraversalSubType? TraversalSubType is a function
// template parameter passed in to the constructor of the face iterator,
// whereas TraversalType is a class template parameter. This lets us decide
// at runtime whether to move along the first or second side of a bicomp (by
// assigning a face_iterator that has been constructed with TraversalSubType
// = first_side or second_side to a face_iterator variable) without any of
// the virtual function overhead that comes with implementing this
// functionality as a more structured form of type erasure. It also allows
// a single face_iterator to be the end iterator of two iterators traversing
// both sides of a bicomp.
public interface EdgeStoragePolicy<E> {
E getValue();
void setValue(E value);
}
public static class StoreEdge<E> implements EdgeStoragePolicy<E> {
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
public static class NoEdge<E> implements EdgeStoragePolicy<E> {
public E getValue() {
throw new UnsupportedOperationException("Edges not stored");
}
public void setValue(E value) {
throw new UnsupportedOperationException("Edges not stored");
}
}
// Time
protected interface TimePolicy<V, E> {
void setEoFirst(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage);
void setEoSecond(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage);
V getFirstVertex(FaceHandle<V, E> anchorHandle);
V getSecondVertex(FaceHandle<V, E> anchorHandle);
}
protected static class CurrentIteration<V, E> implements TimePolicy<V, E> {
public V getFirstVertex(FaceHandle<V, E> anchorHandle) {
return anchorHandle.getFirstVertex();
}
public V getSecondVertex(FaceHandle<V, E> anchorHandle) {
return anchorHandle.getSecondVertex();
}
public void setEoFirst(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage) {
edgeStorage.setValue(anchorHandle.getFirstEdge());
}
public void setEoSecond(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage) {
edgeStorage.setValue(anchorHandle.getSecondEdge());
}
};
protected static class PreviousIteration<V, E> implements TimePolicy<V, E> {
public V getFirstVertex(FaceHandle<V, E> anchorHandle) {
return anchorHandle.getOldFirstVertex();
}
public V getSecondVertex(FaceHandle<V, E> anchorHandle) {
return anchorHandle.getOldSecondVertex();
}
public void setEoFirst(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage) {
edgeStorage.setValue(anchorHandle.getOldFirstEdge());
}
public void setEoSecond(FaceHandle<V, E> anchorHandle, EdgeStoragePolicy<E> edgeStorage) {
edgeStorage.setValue(anchorHandle.getOldSecondEdge());
}
};
// Policies for defining traversal properties
// VisitorType
protected interface VisitorPolicy<V, E> {
V getVertex(FaceIteratorSingleSide<V, E> faceIteratorSingleSide);
E getEdge(FaceIteratorSingleSide<V, E> faceIteratorSingleSide);
}
protected static class LeadVisitor<V, E> implements VisitorPolicy<V, E> {
public V getVertex(FaceIteratorSingleSide<V, E> faceIteratorSingleSide) {
return faceIteratorSingleSide.lead;
}
public E getEdge(FaceIteratorSingleSide<V, E> faceIteratorSingleSide) {
return faceIteratorSingleSide.edgeStorage.getValue();
}
};
protected static class FollowVisitor<V, E> implements VisitorPolicy<V, E> {
public V getVertex(FaceIteratorSingleSide<V, E> faceIteratorSingleSide) {
return faceIteratorSingleSide.follow;
}
public E getEdge(FaceIteratorSingleSide<V, E> faceIteratorSingleSide) {
return faceIteratorSingleSide.edgeStorage.getValue();
}
};
// TraversalSubType
protected interface TraversalSubTypePolicy<V, E> {
void setLead(FaceIteratorSingleSide<V, E> faceIteratorSingleSide, FaceHandle<V, E> anchorHandle);
}
protected static class FirstSide<V, E> implements TraversalSubTypePolicy<V, E> {
public void setLead(FaceIteratorSingleSide<V, E> faceIteratorSingleSide, FaceHandle<V, E> anchorHandle) {
faceIteratorSingleSide.lead = faceIteratorSingleSide.getFirstVertex(anchorHandle);
faceIteratorSingleSide.setEoFirst(anchorHandle);
}
}; //for single_side
protected static class SecondSide<V, E> implements TraversalSubTypePolicy<V, E> {
public void setLead(FaceIteratorSingleSide<V, E> faceIteratorSingleSide, FaceHandle<V, E> anchorHandle) {
faceIteratorSingleSide.lead = faceIteratorSingleSide.getSecondVertex(anchorHandle);
faceIteratorSingleSide.setEoSecond(anchorHandle);
}
}; //for single_side
//specialization for TraversalType = traverse_vertices
protected abstract static class FaceIteratorSingleSide<V, E> {
protected VisitorPolicy<V, E> visitorPolicy;
protected TimePolicy<V, E> timePolicy;
protected V lead;
protected V follow;
protected EdgeStoragePolicy<E> edgeStorage;
protected Map<V, FaceHandle<V, E>> faceHandleMap;
protected FaceIteratorSingleSide(VisitorPolicy<V, E> visitor,
TimePolicy<V, E> timePolicy) {
this.visitorPolicy = visitor;
this.timePolicy = timePolicy;
this.lead = null;
this.follow = null;
}
protected FaceIteratorSingleSide(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
FaceHandle<V, E> anchorHandle,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
this.visitorPolicy = visitorPolicy;
this.timePolicy = timePolicy;
this.follow = anchorHandle.getAnchor();
this.faceHandleMap = faceHandleMap;
traversalSubType.setLead(this, anchorHandle);
}
protected FaceIteratorSingleSide(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
V anchor,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
this.visitorPolicy = visitorPolicy;
this.timePolicy = timePolicy;
this.follow = anchor;
this.faceHandleMap = faceHandleMap;
traversalSubType.setLead(this, faceHandleMap.get(anchor));
}
@Override
public abstract FaceIteratorSingleSide<V, E> clone();
protected V getFirstVertex(FaceHandle<V, E> anchorHandle) {
return timePolicy.getFirstVertex(anchorHandle);
}
protected V getSecondVertex(FaceHandle<V, E> anchorHandle) {
return timePolicy.getSecondVertex(anchorHandle);
}
abstract protected void setEoFirst(FaceHandle<V, E> anchorHandle);
abstract protected void setEoSecond(FaceHandle<V, E> anchorHandle);
public void increment() {
FaceHandle<V, E> currentFaceHandle = faceHandleMap.get(lead);
V first = getFirstVertex(currentFaceHandle);
V second = getSecondVertex(currentFaceHandle);
if (first == follow) {
follow = lead;
setEoSecond(currentFaceHandle);
lead = second;
} else if (second == follow) {
follow = lead;
setEoFirst(currentFaceHandle);
lead = first;
} else {
lead = follow = null;
}
}
public boolean equals(FaceIteratorSingleSide other) {
return lead.equals(other.lead) && follow.equals(other.follow);
}
public E getEdge() {
return visitorPolicy.getEdge(this);
}
public V getVertex() {
return visitorPolicy.getVertex(this);
}
public boolean hasNext() {
return lead != null || follow != null;
}
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
protected abstract static class FaceIteratorBothSides<V, E> {
protected FaceIteratorSingleSide<V, E> firstItr;
protected FaceIteratorSingleSide<V, E> secondItr;
protected boolean isFirstActive;
protected boolean firstIncrement;
FaceIteratorBothSides() {
}
public void increment() {
if (firstIncrement) {
firstItr.increment();
secondItr.increment();
firstIncrement = false;
} else if (isFirstActive) {
firstItr.increment();
} else {
secondItr.increment();
}
isFirstActive = !isFirstActive;
}
public boolean equals(FaceIteratorBothSides other) {
//Want this iterator to be equal to the "end" iterator when at least
//one of the iterators has reached the root of the current bicomp.
//This isn't ideal, but it works.
return (firstItr.equals(other.firstItr) || secondItr.equals(other.secondItr));
}
protected E getEdge() {
return isFirstActive ? firstItr.getEdge() : secondItr.getEdge();
}
protected V getVertex() {
return isFirstActive ? firstItr.getVertex() : secondItr.getVertex();
}
public boolean hasNext() {
return (firstItr == null || !firstItr.hasNext())
&& (secondItr == null || !secondItr.hasNext());
}
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
public static class FaceIteratorSingleSideVertex<V, E> extends FaceIteratorSingleSide<V, E> implements Iterator<V> {
public FaceIteratorSingleSideVertex(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy) {
super(visitorPolicy, timePolicy);
this.edgeStorage = new NoEdge<E>();
}
public FaceIteratorSingleSideVertex(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
FaceHandle<V, E> anchorHandle,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
super(visitorPolicy, timePolicy, anchorHandle, faceHandleMap, traversalSubType);
this.edgeStorage = new NoEdge<E>();
}
public FaceIteratorSingleSideVertex(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
V anchor,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
super(visitorPolicy, timePolicy, anchor, faceHandleMap, traversalSubType);
this.edgeStorage = new NoEdge<E>();
}
protected void setEoFirst(FaceHandle<V, E> anchorHandle) {
}
protected void setEoSecond(FaceHandle<V, E> anchorHandle) {
}
@Override
public FaceIteratorSingleSideVertex<V, E> clone()
{
FaceIteratorSingleSideVertex<V, E> clone = new FaceIteratorSingleSideVertex<V, E>(
visitorPolicy, timePolicy);
clone.faceHandleMap = this.faceHandleMap;
clone.follow = this.follow;
clone.lead = this.lead;
clone.edgeStorage = this.edgeStorage;
return clone;
}
public V next() {
V value = getVertex();
increment();
return value;
}
}
public static class FaceIteratorSingleSideEdge<V, E> extends FaceIteratorSingleSide<V, E> implements Iterator<E> {
public FaceIteratorSingleSideEdge(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy) {
super(visitorPolicy, timePolicy);
this.edgeStorage = new StoreEdge<E>();
}
public FaceIteratorSingleSideEdge(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
FaceHandle<V, E> anchorHandle,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
super(visitorPolicy, timePolicy, anchorHandle, faceHandleMap, traversalSubType);
this.edgeStorage = new StoreEdge<E>();
}
public FaceIteratorSingleSideEdge(VisitorPolicy<V, E> visitorPolicy,
TimePolicy<V, E> timePolicy,
V anchor,
Map<V, FaceHandle<V, E>> faceHandleMap,
TraversalSubTypePolicy<V, E> traversalSubType) {
super(visitorPolicy, timePolicy, anchor, faceHandleMap, traversalSubType);
this.edgeStorage = new StoreEdge<E>();
}
protected void setEoFirst(FaceHandle<V, E> anchorHandle) {
timePolicy.setEoFirst(anchorHandle, edgeStorage);
}
protected void setEoSecond(FaceHandle<V, E> anchorHandle) {
timePolicy.setEoSecond(anchorHandle, edgeStorage);
}
@Override
public FaceIteratorSingleSideEdge<V, E> clone()
{
FaceIteratorSingleSideEdge<V, E> clone = new FaceIteratorSingleSideEdge<V, E>(
visitorPolicy, timePolicy);
clone.faceHandleMap = this.faceHandleMap;
clone.follow = this.follow;
clone.lead = this.lead;
clone.edgeStorage = this.edgeStorage;
return clone;
}
public E next() {
E value = getEdge();
increment();
return value;
}
}
public static class FaceIteratorBothSidesVertex<V, E> extends FaceIteratorBothSides<V, E> implements Iterator<V> {
protected FaceIteratorBothSidesVertex() {
}
protected FaceIteratorBothSidesVertex(TimePolicy<V, E> timePolicy, FaceHandle<V, E> anchorHandle, Map<V, FaceHandle<V, E>> faceHandleMap) {
firstItr = new FaceIteratorSingleSideVertex<V, E>(new FollowVisitor<V, E>(), timePolicy, anchorHandle, faceHandleMap, new FirstSide<V, E>());
secondItr = new FaceIteratorSingleSideVertex<V, E>(new FollowVisitor<V, E>(), timePolicy, anchorHandle, faceHandleMap, new SecondSide<V, E>());
isFirstActive = true;
firstIncrement = true;
}
protected FaceIteratorBothSidesVertex(TimePolicy<V, E> timePolicy, V anchor, Map<V, FaceHandle<V, E>> faceHandleMap) {
firstItr = new FaceIteratorSingleSideVertex<V, E>(new FollowVisitor<V, E>(), timePolicy, faceHandleMap.get(anchor), faceHandleMap, new FirstSide<V, E>());
secondItr = new FaceIteratorSingleSideVertex<V, E>(new FollowVisitor<V, E>(), timePolicy, faceHandleMap.get(anchor), faceHandleMap, new SecondSide<V, E>());
isFirstActive = true;
firstIncrement = true;
}
@Override
public FaceIteratorBothSidesVertex<V, E> clone()
{
FaceIteratorBothSidesVertex<V, E> clone = new FaceIteratorBothSidesVertex<V, E>();
clone.firstItr = firstItr.clone();
clone.secondItr = secondItr.clone();
clone.isFirstActive = isFirstActive;
clone.firstIncrement = firstIncrement;
return clone;
}
public V next() {
V value = getVertex();
increment();
return value;
}
}
public static class FaceIteratorBothSidesEdge<V, E> extends FaceIteratorBothSides<V, E> implements Iterator<E> {
protected FaceIteratorBothSidesEdge() {
}
protected FaceIteratorBothSidesEdge(TimePolicy<V, E> timePolicy, FaceHandle<V, E> anchorHandle, Map<V, FaceHandle<V, E>> faceHandleMap) {
firstItr = new FaceIteratorSingleSideEdge<V, E>(new FollowVisitor<V, E>(), timePolicy, anchorHandle, faceHandleMap, new FirstSide<V, E>());
secondItr = new FaceIteratorSingleSideEdge<V, E>(new FollowVisitor<V, E>(), timePolicy, anchorHandle, faceHandleMap, new SecondSide<V, E>());
isFirstActive = true;
firstIncrement = true;
}
protected FaceIteratorBothSidesEdge(TimePolicy<V, E> timePolicy, V anchor, Map<V, FaceHandle<V, E>> faceHandleMap) {
firstItr = new FaceIteratorSingleSideEdge<V, E>(new FollowVisitor<V, E>(), timePolicy, faceHandleMap.get(anchor), faceHandleMap, new FirstSide<V, E>());
secondItr = new FaceIteratorSingleSideEdge<V, E>(new FollowVisitor<V, E>(), timePolicy, faceHandleMap.get(anchor), faceHandleMap, new SecondSide<V, E>());
isFirstActive = true;
firstIncrement = true;
}
@Override
public FaceIteratorBothSidesEdge<V, E> clone()
{
FaceIteratorBothSidesEdge<V, E> clone = new FaceIteratorBothSidesEdge<V, E>();
clone.firstItr = firstItr.clone();
clone.secondItr = secondItr.clone();
clone.isFirstActive = isFirstActive;
clone.firstIncrement = firstIncrement;
return clone;
}
public E next() {
E value = getEdge();
increment();
return value;
}
}
}
}