andres::graph
grid-graph.hxx
1 
2 #pragma once
3 #ifndef ANDRES_GRAPH_GRID_GRAPH_HXX
4 #define ANDRES_GRAPH_GRID_GRAPH_HXX
5 
6 #include <cassert>
7 #include <cstddef>
8 #include <cmath>
9 #include <iterator>
10 #include <array>
11 #include <initializer_list>
12 
13 #include "adjacency.hxx"
14 #include "visitor.hxx"
15 
16 namespace andres {
17 
18 namespace graph {
19 
21 template <unsigned char D = 2, class VISITOR = IdleGraphVisitor<std::size_t> >
22 class GridGraph {
23 public:
24  typedef std::size_t size_type;
25  typedef VISITOR Visitor;
27 
28  static const size_type DIMENSION = static_cast<size_type> (D);
29 
30  typedef std::array<size_type, DIMENSION> VertexCoordinate;
31 
35  struct EdgeCoordinate {
36  EdgeCoordinate(const VertexCoordinate&, const size_type, bool = false);
47  };
48 
50  // \cond SUPPRESS_DOXYGEN
51  class AdjacencyIterator
52  : public std::iterator <
53  std::random_access_iterator_tag,
54  const AdjacencyType
55  > {
56  public:
57  typedef GridGraph<DIMENSION, Visitor> GraphType;
58  typedef std::iterator <
59  std::random_access_iterator_tag,
60  const AdjacencyType
61  > Base;
62  typedef typename Base::difference_type difference_type;
63  typedef typename Base::pointer pointer;
64  typedef typename Base::reference reference;
65 
66  AdjacencyIterator();
67  AdjacencyIterator(const GraphType&);
68  AdjacencyIterator(const GraphType&, const size_type);
69  AdjacencyIterator(const GraphType&, const size_type, const size_type);
70 
71  // increment and decrement
72  AdjacencyIterator& operator+=(const difference_type);
73  AdjacencyIterator& operator-=(const difference_type);
74  AdjacencyIterator& operator++(); // prefix
75  AdjacencyIterator& operator--(); // prefix
76  AdjacencyIterator operator++(int); // postfix
77  AdjacencyIterator operator--(int); // postfix
78  AdjacencyIterator operator+(const difference_type) const;
79  AdjacencyIterator operator-(const difference_type) const;
80  difference_type operator-(const AdjacencyIterator&) const;
81 
82  // comparison
83  bool operator==(const AdjacencyIterator&) const;
84  bool operator!=(const AdjacencyIterator&) const;
85  bool operator<(const AdjacencyIterator&) const;
86  bool operator<=(const AdjacencyIterator&) const;
87  bool operator>(const AdjacencyIterator&) const;
88  bool operator>=(const AdjacencyIterator&) const;
89 
90  // access
91  reference operator*();
92  pointer operator->();
93  reference operator[](const difference_type);
94 
95  protected:
96  const GraphType* graph_;
97  size_type vertex_;
98  size_type adjacencyIndex_;
99  AdjacencyType adjacency_;
100  };
101 
102  class VertexIterator
103  : public AdjacencyIterator {
104  public:
105  typedef GridGraph<DIMENSION, Visitor> GraphType;
106  typedef AdjacencyIterator Base;
107  typedef const size_type value_type;
108  typedef typename Base::difference_type difference_type;
109  typedef value_type* pointer;
110  typedef value_type& reference;
111 
112  VertexIterator();
113  VertexIterator(const VertexIterator&);
114  VertexIterator(const AdjacencyIterator&);
115  VertexIterator(const GraphType&);
116  VertexIterator(const GraphType&, const size_type);
117  VertexIterator(const GraphType&, const size_type, const size_type);
118 
119  // access
120  value_type operator*() const;
121  value_type operator[](const difference_type) const;
122 
123  void coordinate(VertexCoordinate&) const;
124  private:
125  pointer operator->() const;
126  };
127 
128  class EdgeIterator
129  : public AdjacencyIterator {
130  public:
131  typedef GridGraph<DIMENSION, Visitor> GraphType;
132  typedef AdjacencyIterator Base;
133  typedef const size_type value_type;
134  typedef typename Base::difference_type difference_type;
135  typedef value_type* pointer;
136  typedef value_type& reference;
137 
138  EdgeIterator();
139  EdgeIterator(const EdgeIterator&);
140  EdgeIterator(const AdjacencyIterator&);
141  EdgeIterator(const GraphType&);
142  EdgeIterator(const GraphType&, const size_type);
143  EdgeIterator(const GraphType&, const size_type, const size_type);
144 
145  // access
146  value_type operator*() const;
147  value_type operator[](const difference_type) const;
148  private:
149  pointer operator->() const;
150  };
151  // \endcond
152 
153  // construction
154  GridGraph(const Visitor& = Visitor());
155  GridGraph(const VertexCoordinate&, const Visitor& = Visitor());
156  GridGraph(const std::initializer_list<std::size_t>, const Visitor& = Visitor());
157  void assign(const Visitor& = Visitor());
158  void assign(const VertexCoordinate&, const Visitor& = Visitor());
159 
160  // iterator access (compatible with Digraph)
161  VertexIterator verticesFromVertexBegin(const size_type) const;
162  VertexIterator verticesFromVertexEnd(const size_type) const;
163  VertexIterator verticesToVertexBegin(const size_type) const;
164  VertexIterator verticesToVertexEnd(const size_type) const;
165  EdgeIterator edgesFromVertexBegin(const size_type) const;
166  EdgeIterator edgesFromVertexEnd(const size_type) const;
167  EdgeIterator edgesToVertexBegin(const size_type) const;
168  EdgeIterator edgesToVertexEnd(const size_type) const;
169  AdjacencyIterator adjacenciesFromVertexBegin(const size_type) const;
170  AdjacencyIterator adjacenciesFromVertexEnd(const size_type) const;
171  AdjacencyIterator adjacenciesToVertexBegin(const size_type) const;
172  AdjacencyIterator adjacenciesToVertexEnd(const size_type) const;
173 
174  // access (compatible with Digraph)
175  size_type numberOfVertices() const;
176  size_type numberOfEdges() const;
179  size_type vertexOfEdge(const size_type, const size_type) const;
180  size_type edgeFromVertex(const size_type, const size_type) const;
181  size_type edgeToVertex(const size_type, const size_type) const;
182  size_type vertexFromVertex(const size_type, const size_type) const;
183  size_type vertexToVertex(const size_type, const size_type) const;
186  std::pair<bool, size_type> findEdge(const size_type, const size_type) const;
187  bool multipleEdgesEnabled() const;
188 
189  size_type insertEdge(const size_type, const size_type) const;
190 
191  size_type shape(const size_type) const;
192 
193  size_type vertex(const VertexCoordinate&) const;
194  void vertex(const size_type, VertexCoordinate&) const;
195  size_type edge(const EdgeCoordinate&) const;
196  void edge(const size_type, EdgeCoordinate&) const;
197 
198 private:
199  size_type vertexFromVertex(const VertexCoordinate&, const size_type, size_type&, bool&) const;
200  void adjacencyFromVertex(const VertexCoordinate&, const size_type, size_type&, size_type&) const;
201 
202  // Member variables
203  VertexCoordinate shape_;
204  std::array<size_type, DIMENSION> edgeIndexOffsets_;
205  std::array<size_type, DIMENSION> vertexIndexOffsets_;
206  std::array<VertexCoordinate, DIMENSION> edgeShapes_;
207  size_type numberOfVertices_;
208  const size_type& numberOfEdges_;
209  Visitor visitor_;
210 };
211 
220 template<unsigned char D, class VISITOR>
221 inline
223  const Visitor& visitor
224 )
225 : GridGraph(VertexCoordinate({}), visitor) // Chain-call Constructor
226 {}
227 
233 template<unsigned char D, class VISITOR>
234 inline
236  const VertexCoordinate& shape,
237  const Visitor& visitor
238 )
239  : numberOfEdges_ (edgeIndexOffsets_[DIMENSION - 1]) {
240  assign(shape, visitor);
241 }
242 
248 template<unsigned char D, class VISITOR>
249 inline
251  std::initializer_list<std::size_t> shape,
252  const Visitor& visitor
253 )
254  : numberOfEdges_ (edgeIndexOffsets_[DIMENSION - 1]) {
255  assert(shape.size()==D);
256  VertexCoordinate vCoord;
257  std::copy(shape.begin(), shape.end(), vCoord.begin());
258  assign(vCoord, visitor);
259 }
260 
266 template<unsigned char D, class VISITOR>
267 inline void
269  const Visitor& visitor
270 ) {
271  VertexCoordinate shape;
272  std::fill(shape.begin(), shape.end(), 0);
273  assign(shape, visitor);
274 }
275 
281 template<unsigned char D, class VISITOR>
282 inline void
284  const VertexCoordinate& shape,
285  const Visitor& visitor
286 ) {
287  shape_ = shape;
288  visitor_ = visitor;
289 
290  // Set vertex offsets for fast vertex indexing.
291  {
292  size_type cumprod = 1;
293  size_type i;
294  for(i = 0; i < DIMENSION; ++i) {
295  vertexIndexOffsets_[i] = cumprod;
296  cumprod *= shape_[i];
297  }
298  numberOfVertices_ = cumprod;
299  }
300  {
301  size_type edgeIndexOffset = 0; // First edge is at offset 0
302  for(size_type i = 0; i < DIMENSION; ++i) {
303  VertexCoordinate& edgeShape = edgeShapes_[i];
304  edgeShape = shape_; // the i-th dimension of the edges along the i-th dimension is 1 less
305  if(edgeShape[i] > 0) { // If already zero, no need to reduce.
306  --edgeShape[i];
307  }
308  {
309  //
310  size_type cumprod = edgeShape[0];
311  for(size_type j = 1; j < DIMENSION; ++j) {
312  cumprod *= edgeShape[j];
313  }
314  edgeIndexOffsets_[i] = (edgeIndexOffset += cumprod);
315  }
316  }
317  }
318 }
319 
328 template<unsigned char D, class VISITOR>
331  const size_type vertex
332 ) const {
333  return VertexIterator(*this, vertex, 0);
334 }
335 
344 template<unsigned char D, class VISITOR>
347  const size_type vertex
348 ) const {
349  return VertexIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
350 }
351 
360 template<unsigned char D, class VISITOR>
363  const size_type vertex
364 ) const {
365  return VertexIterator(*this, vertex, 0);
366 }
367 
376 template<unsigned char D, class VISITOR>
379  const size_type vertex
380 ) const {
381  return VertexIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
382 }
383 
392 template<unsigned char D, class VISITOR>
395  const size_type vertex
396 ) const {
397  return EdgeIterator(*this, vertex, 0);
398 }
399 
408 template<unsigned char D, class VISITOR>
411  const size_type vertex
412 ) const {
413  return EdgeIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
414 }
415 
424 template<unsigned char D, class VISITOR>
427  const size_type vertex
428 ) const {
429  return EdgeIterator(*this, vertex, 0);
430 }
431 
440 template<unsigned char D, class VISITOR>
443  const size_type vertex
444 ) const {
445  return EdgeIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
446 }
447 
456 template<unsigned char D, class VISITOR>
459  const size_type vertex
460 ) const {
461  return AdjacencyIterator(*this, vertex, 0);
462 }
463 
472 template<unsigned char D, class VISITOR>
475  const size_type vertex
476 ) const {
477  return AdjacencyIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
478 }
479 
488 template<unsigned char D, class VISITOR>
491  const size_type vertex
492 ) const {
493  return AdjacencyIterator(*this, vertex, 0);
494 }
495 
504 template<unsigned char D, class VISITOR>
507  const size_type vertex
508 ) const {
509  return AdjacencyIterator(*this, vertex, numberOfEdgesFromVertex(vertex));
510 }
511 
514 template<unsigned char D, class VISITOR>
515 inline typename GridGraph<D, VISITOR>::size_type
517  return numberOfVertices_;
518 }
519 
522 template<unsigned char D, class VISITOR>
523 inline typename GridGraph<D, VISITOR>::size_type
525  return numberOfEdges_;
526 }
527 
534 template<unsigned char D, class VISITOR>
535 inline typename GridGraph<D, VISITOR>::size_type
537  const size_type vertex
538 ) const {
539  assert(vertex < numberOfVertices());
540  VertexCoordinate edgeCoordinate;
541  this->vertex(vertex, edgeCoordinate);
542  size_type numEdgesFromVertex = 0;
543  for(size_type i = 0; i < DIMENSION; ++i) {
544  const size_type& coordinate = edgeCoordinate[i];
545  if(coordinate > 0) {
546  ++numEdgesFromVertex;
547  }
548  if(coordinate < (shape_[i] - 1)) {
549  ++numEdgesFromVertex;
550  }
551  }
552  return numEdgesFromVertex;
553 }
554 
561 template<unsigned char D, class VISITOR>
562 inline typename GridGraph<D, VISITOR>::size_type
564  const size_type vertex
565 ) const {
566  return numberOfEdgesFromVertex(vertex);
567 }
568 
574 template<unsigned char D, class VISITOR>
575 inline typename GridGraph<D, VISITOR>::size_type
577  const size_type edge,
578  const size_type j
579 ) const {
580  assert(edge < numberOfEdges());
581  assert(j < 2);
582  EdgeCoordinate edgeCoordinate;
583  this->edge(edge, edgeCoordinate);
584  size_type pivotIndex = vertex(edgeCoordinate.pivotCoordinate_);
585  if(j == 0) {
586  return pivotIndex;
587  }
588  else {
589  return pivotIndex + vertexIndexOffsets_[edgeCoordinate.dimension_];
590  }
591 }
592 
601 template<unsigned char D, class VISITOR>
602 inline typename GridGraph<D, VISITOR>::size_type
604  const size_type vertex,
605  const size_type j
606 ) const {
607  assert(j < numberOfEdgesFromVertex(vertex));
608  VertexCoordinate vertexCoordinate;
609  this->vertex(vertex, vertexCoordinate);
610  size_type direction;
611  bool isSmaller;
612  vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
613  if(isSmaller) {
614  VertexCoordinate pivotVertexCoordinate = vertexCoordinate;
615  --pivotVertexCoordinate[direction];
616  return edge(EdgeCoordinate(pivotVertexCoordinate, direction));
617  }
618  else {
619  return edge(EdgeCoordinate(vertexCoordinate, direction));
620  }
621 }
622 
631 template<unsigned char D, class VISITOR>
632 inline typename GridGraph<D, VISITOR>::size_type
634  const size_type vertex,
635  const size_type j
636 ) const {
637  assert(j < numberOfEdgesToVertex(vertex));
638  return edgeFromVertex(vertex, j);
639 }
640 
650 template<unsigned char D, class VISITOR>
651 inline typename GridGraph<D, VISITOR>::size_type
653  const size_type vertex,
654  const size_type j
655 ) const {
656  assert(j < numberOfEdgesToVertex(vertex));
657  VertexCoordinate vertexCoordinate;
658  this->vertex(vertex, vertexCoordinate);
659  size_type direction;
660  bool isSmaller;
661  return vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
662 }
663 
664 
674 template<unsigned char D, class VISITOR>
675 inline typename GridGraph<D, VISITOR>::size_type
677  const size_type vertex,
678  const size_type j
679 ) const {
680  assert(j < numberOfEdgesToVertex(vertex));
681  return vertexFromVertex(vertex, j);
682 }
683 
688 template<unsigned char D, class VISITOR>
691  const size_type vertex,
692  const size_type j
693 ) const {
694  assert(j < numberOfEdgesToVertex(vertex));
695  size_type direction;
696  size_type adjacentEdgeIndex;
697  size_type adjacentVertexIndex;
698 
699  {
700  VertexCoordinate vertexCoordinate;
701  this->vertex(vertex, vertexCoordinate);
702 
703  adjacencyFromVertex(vertexCoordinate, j, adjacentVertexIndex, adjacentEdgeIndex);
704  }
705  return AdjacencyType(adjacentVertexIndex, adjacentEdgeIndex);
706 }
707 
708 
714 template<unsigned char D, class VISITOR>
717  const size_type vertex,
718  const size_type j
719 ) const {
720  return adjacencyFromVertex(vertex, j);
721 }
722 
732 template<unsigned char D, class VISITOR>
733 inline std::pair<bool, typename GridGraph<D, VISITOR>::size_type>
735  const size_type vertex0,
736  const size_type vertex1
737 ) const {
738  assert(vertex0 < numberOfVertices());
739  assert(vertex1 < numberOfVertices());
740  if(vertex0 < vertex1) {
741  size_type offset = vertex1 - vertex0;
742  size_type i;
743  for(i = 0; i < DIMENSION - 1; ++i) {
744  if(offset == vertexIndexOffsets_[i]) { // edge found unless offset runs across dimension
745  VertexCoordinate vertexCoordinate0;
746  vertex(vertex0, vertexCoordinate0);
747  if(vertexCoordinate0[i] != shape_[i] - 1) { // Check for boundary case
748  const EdgeCoordinate edgeCoordinate(vertexCoordinate0, i, false);
749  const size_type edgeIndex = edge(edgeCoordinate);
750  return std::make_pair(true, edgeIndex);
751  }
752  }
753  }
754  if(offset == vertexIndexOffsets_[i]) { // edge found
755  VertexCoordinate vertexCoordinate0;
756  vertex(vertex0, vertexCoordinate0);
757  const EdgeCoordinate edgeCoordinate(vertexCoordinate0, i, false);
758  const size_type edgeIndex = edge(edgeCoordinate);
759  return std::make_pair(true, edgeIndex);
760  }
761  }
762  else { // On expectation faster to ignore the equal case. (Assuming uniform input distribution)
763  size_type offset = vertex0 - vertex1;
764  size_type i;
765  for(i = 0; i < DIMENSION - 1; ++i) {
766  if(offset == vertexIndexOffsets_[i]) { // edge found unless offset runs across dimensions
767  VertexCoordinate vertexCoordinate1;
768  vertex(vertex1, vertexCoordinate1);
769  if(vertexCoordinate1[i] != shape_[i] - 1) { // Check for boundary case
770  const EdgeCoordinate edgeCoordinate(vertexCoordinate1, i, false);
771  const size_type edgeIndex = edge(edgeCoordinate);
772  return std::make_pair(true, edgeIndex);
773  }
774  }
775  }
776  if(offset == vertexIndexOffsets_[i]) { // edge found unless offset runs across dimensions
777  VertexCoordinate vertexCoordinate1;
778  vertex(vertex1, vertexCoordinate1);
779  const EdgeCoordinate edgeCoordinate(vertexCoordinate1, i, false);
780  const size_type edgeIndex = edge(edgeCoordinate);
781  return std::make_pair(true, edgeIndex);
782  }
783  }
784  return std::make_pair(false, 0);
785 }
786 
791 template<unsigned char D, class VISITOR>
792 inline bool
794  return false;
795 }
796 
803 template<unsigned char D, class VISITOR>
804 inline typename GridGraph<D, VISITOR>::size_type
806  const size_type vertexIndex0,
807  const size_type vertexIndex1
808 ) const {
809  assert(vertexIndex0 < numberOfVertices());
810  assert(vertexIndex1 < numberOfVertices());
811 
812  std::pair<bool, std::size_t> p = findEdge(vertexIndex0, vertexIndex1);
813  if(p.first == true) {
814  return p.second;
815  } else {
816  throw std::runtime_error("Edge not found.");
817  }
818 }
819 
825 template<unsigned char D, class VISITOR>
826 void
828  size_type vertexIndex,
829  VertexCoordinate& vertexCoordinate
830 ) const {
831  assert(vertexIndex < numberOfVertices_);
832  size_type i;
833  for(i = 0; i < DIMENSION - 1; ++i) {
834  vertexCoordinate[i] = vertexIndex % shape_[i];
835  vertexIndex = vertexIndex / shape_[i];
836  }
837  vertexCoordinate[i] = vertexIndex;
838 }
839 
844 template<unsigned char D, class VISITOR>
845 inline typename GridGraph<D, VISITOR>::size_type
847  const size_type dimension
848 ) const {
849  return shape_[dimension];
850 }
851 
857 template<unsigned char D, class VISITOR>
860  const VertexCoordinate& vertexCoordinate
861 ) const {
862  size_type index = vertexCoordinate[DIMENSION - 1];
863  for(size_type i = DIMENSION - 1; i > 0; --i) {
864  index = index * shape_[i - 1] + vertexCoordinate[i - 1];
865  }
866  return index;
867 }
868 
876 template<unsigned char D, class VISITOR>
877 inline typename GridGraph<D, VISITOR>::size_type
879  const EdgeCoordinate& edgeCoordinate
880 ) const {
881  assert(edgeCoordinate.dimension_ < DIMENSION);
882  const size_type& dimension = edgeCoordinate.dimension_;
883  const VertexCoordinate& pivotCoordinate = edgeCoordinate.pivotCoordinate_;
884  const VertexCoordinate& edgeShape = edgeShapes_[dimension];
885 
886  // size_type index = mapCoordinateToIndex(edgeCoordinate,edgeShape);
887  size_type index = pivotCoordinate[DIMENSION - 1];
888  for(size_type i = DIMENSION - 1; i > 0; --i) {
889  index = index * edgeShape[i - 1] + pivotCoordinate[i - 1];
890  }
891  if(dimension > 0) {
892  const size_type& offset = edgeIndexOffsets_[dimension - 1];
893  index += offset;
894  }
895  return index;
896 }
897 
908 template<unsigned char D, class VISITOR>
909 inline void
911  size_type edgeIndex,
912  EdgeCoordinate& edgeCoordinate
913 ) const {
914  // WARNING: If the assertion does not hold, the code will scan until an unlikely condition.
915  assert(edgeIndex < numberOfEdges());
916  size_type& direction = edgeCoordinate.dimension_;
917  // Find the direction as the last edge offset:
918  for(direction = 0; edgeIndex >= edgeIndexOffsets_[direction]; ++direction);
919  if(direction > 0) { // Not needed, but saves one memory lookup.
920  const size_type& offset = edgeIndexOffsets_[direction - 1];
921  edgeIndex -= offset;
922  }
923  const VertexCoordinate& edgeShape = edgeShapes_[direction];
924  // mapEdgeIndexToCoordinate
925  {
926  VertexCoordinate& pivotCoordinate = edgeCoordinate.pivotCoordinate_;
927  size_type i;
928  for(i = 0; i < DIMENSION - 1; ++i) {
929  pivotCoordinate[i] = edgeIndex % edgeShape[i];
930  edgeIndex = edgeIndex / edgeShape[i];
931  }
932  pivotCoordinate[i] = edgeIndex;
933  }
934 }
935 
936 
952 template<unsigned char D, class VISITOR>
953 inline typename GridGraph<D, VISITOR>::size_type
955  const VertexCoordinate& vertexCoordinate,
956  const size_type j,
957  size_type& direction,
958  bool& isSmaller
959 ) const {
960  assert(vertex(vertexCoordinate) < numberOfVertices());
961  VertexCoordinate modifieableVertexCoordinate = vertexCoordinate;
962  size_type cur_j = 0;
963  for(size_type i = DIMENSION; i > 0; --i) {
964  if(vertexCoordinate[i - 1] > 0) { // edge exists
965  if(cur_j == j) {
966  direction = i - 1;
967  isSmaller = true;
968  --modifieableVertexCoordinate[i - 1];
969  const size_type vertexIndex = vertex(modifieableVertexCoordinate);
970  return vertexIndex;
971  }
972  ++cur_j;
973  }
974  }
975  for(size_type i = 0; i < DIMENSION; ++i) {
976  if(vertexCoordinate[i] < shape_[i] - 1) { // edge exists
977  if(cur_j == j) {
978  direction = i;
979  isSmaller = false;
980  ++modifieableVertexCoordinate[i];
981  const size_type vertexIndex = vertex(modifieableVertexCoordinate);
982  return vertexIndex;
983  }
984  ++cur_j;
985  }
986  }
987  throw std::out_of_range("vertex neighbor index out of range.");
988 }
989 
990 template<unsigned char D, class VISITOR>
991 inline void
993  const VertexCoordinate& vertexCoordinate,
994  const size_type j,
995  size_type& adjacentVertexIndex,
996  size_type& adjacentEdgeIndex
997 ) const {
998  assert(vertex(vertexCoordinate) < numberOfVertices());
999  size_type direction;
1000  bool isSmaller;
1001  adjacentVertexIndex = vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
1002  if(isSmaller) {
1003  VertexCoordinate pivotVertexCoordinate = vertexCoordinate;
1004  --pivotVertexCoordinate[direction];
1005  adjacentEdgeIndex = edge(EdgeCoordinate(pivotVertexCoordinate, direction));
1006  }
1007  else {
1008  adjacentEdgeIndex = edge(EdgeCoordinate(vertexCoordinate, direction));
1009  }
1010 
1011 }
1012 
1023 template<unsigned char D, class VISITOR>
1025  const VertexCoordinate& pivotCoordinate,
1026  const size_type dimension,
1027  const bool isSmaller
1028 )
1029  : pivotCoordinate_(pivotCoordinate),
1030  dimension_(dimension) {
1031  if(isSmaller) {
1032  assert(pivotCoordinate_[dimension] > 0);
1033  --pivotCoordinate_[dimension];
1034  }
1035 }
1036 
1040 template<unsigned char D, class VISITOR>
1042 }
1043 
1044 
1045 // \cond SUPPRESS_DOXYGEN
1046 
1047 // implementation of AdjacencyIterator
1048 
1049 template<unsigned char D, class VISITOR>
1050 inline
1052  : vertex_(0),
1053  adjacencyIndex_(0),
1054  adjacency_()
1055 {}
1056 template<unsigned char D, class VISITOR>
1057 inline
1059  const GraphType& graph
1060 )
1061  : graph_(&graph),
1062  vertex_(0),
1063  adjacencyIndex_(0),
1064  adjacency_()
1065 {}
1066 
1067 template<unsigned char D, class VISITOR>
1068 inline
1069 GridGraph<D, VISITOR>::AdjacencyIterator::AdjacencyIterator(
1070  const GraphType& graph,
1071  const size_type vertex
1072 )
1073  : graph_(&graph),
1074  vertex_(vertex),
1075  adjacencyIndex_(0),
1076  adjacency_() {
1077  assert(vertex < graph.numberOfVertices());
1078 }
1079 
1080 template<unsigned char D, class VISITOR>
1081 inline
1082 GridGraph<D, VISITOR>::AdjacencyIterator::AdjacencyIterator(
1083  const GraphType& graph,
1084  const size_type vertex,
1085  const size_type adjacencyIndex
1086 )
1087  : graph_(&graph),
1088  vertex_(vertex),
1089  adjacencyIndex_(adjacencyIndex),
1090  adjacency_() {
1091  assert(vertex < graph.numberOfVertices());
1092  assert(adjacencyIndex <= graph.numberOfVertices());
1093 }
1094 
1095 template<unsigned char D, class VISITOR>
1096 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1097 GridGraph<D, VISITOR>::AdjacencyIterator::operator+=(
1098  const difference_type d
1099 ) {
1100  adjacencyIndex_ += d;
1101  return *this;
1102 }
1103 
1104 template<unsigned char D, class VISITOR>
1105 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1106 GridGraph<D, VISITOR>::AdjacencyIterator::operator-=(
1107  const difference_type d
1108 ) {
1109  adjacencyIndex_ -= d;
1110  return *this;
1111 }
1112 
1113 template<unsigned char D, class VISITOR>
1114 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1115 GridGraph<D, VISITOR>::AdjacencyIterator::operator++() {
1116  ++adjacencyIndex_;
1117  return *this;
1118 }
1119 
1120 template<unsigned char D, class VISITOR>
1121 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1122 GridGraph<D, VISITOR>::AdjacencyIterator::operator--() {
1123  --adjacencyIndex_;
1124  return *this;
1125 }
1126 
1127 template<unsigned char D, class VISITOR>
1128 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1129 GridGraph<D, VISITOR>::AdjacencyIterator::operator++(int) {
1130  AdjacencyIterator copy = *this;
1131  ++adjacencyIndex_;
1132  return copy;
1133 }
1134 
1135 template<unsigned char D, class VISITOR>
1136 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1137 GridGraph<D, VISITOR>::AdjacencyIterator::operator--(int) {
1138  AdjacencyIterator copy = *this;
1139  --adjacencyIndex_;
1140  return copy;
1141 }
1142 
1143 template<unsigned char D, class VISITOR>
1144 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1145 GridGraph<D, VISITOR>::AdjacencyIterator::operator+(
1146  const difference_type d
1147 ) const {
1148  AdjacencyIterator copy = *this;
1149  copy += d;
1150  return copy;
1151 }
1152 
1153 template<unsigned char D, class VISITOR>
1154 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1155 GridGraph<D, VISITOR>::AdjacencyIterator::operator-(
1156  const difference_type d
1157 ) const {
1158  AdjacencyIterator copy = *this;
1159  copy -= d;
1160  return copy;
1161 }
1162 
1163 template<unsigned char D, class VISITOR>
1164 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::difference_type
1165 GridGraph<D, VISITOR>::AdjacencyIterator::operator-(
1166  const AdjacencyIterator& adjacencyIterator
1167 ) const {
1168  return adjacencyIndex_ - adjacencyIterator.adjacencyIndex_;
1169 }
1170 
1171 template<unsigned char D, class VISITOR>
1172 inline bool
1173 GridGraph<D, VISITOR>::AdjacencyIterator::operator==(
1174  const AdjacencyIterator& other
1175 ) const {
1176  return adjacencyIndex_ == other.adjacencyIndex_
1177  && vertex_ == other.vertex_
1178  && graph_ == other.graph_;
1179 }
1180 
1181 template<unsigned char D, class VISITOR>
1182 inline bool
1183 GridGraph<D, VISITOR>::AdjacencyIterator::operator!=(
1184  const AdjacencyIterator& other
1185 ) const {
1186  return adjacencyIndex_ != other.adjacencyIndex_
1187  || vertex_ != other.vertex_
1188  || graph_ != other.graph_;
1189 }
1190 
1191 template<unsigned char D, class VISITOR>
1192 inline bool
1193 GridGraph<D, VISITOR>::AdjacencyIterator::operator<(
1194  const AdjacencyIterator& other
1195 ) const {
1196  return adjacencyIndex_ < other.adjacencyIndex_
1197  && vertex_ == other.vertex_
1198  && graph_ == other.graph_;
1199 }
1200 
1201 template<unsigned char D, class VISITOR>
1202 inline bool
1203 GridGraph<D, VISITOR>::AdjacencyIterator::operator<=(
1204  const AdjacencyIterator& other
1205 ) const {
1206  return adjacencyIndex_ <= other.adjacencyIndex_
1207  && vertex_ == other.vertex_
1208  && graph_ == other.graph_;
1209 }
1210 
1211 template<unsigned char D, class VISITOR>
1212 inline bool
1213 GridGraph<D, VISITOR>::AdjacencyIterator::operator>(
1214  const AdjacencyIterator& other
1215 ) const {
1216  return adjacencyIndex_ > other.adjacencyIndex_
1217  && vertex_ == other.vertex_
1218  && graph_ == other.graph_;
1219 }
1220 
1221 template<unsigned char D, class VISITOR>
1222 inline bool
1223 GridGraph<D, VISITOR>::AdjacencyIterator::operator>=(
1224  const AdjacencyIterator& other
1225 ) const {
1226  return adjacencyIndex_ >= other.adjacencyIndex_
1227  && vertex_ == other.vertex_
1228  && graph_ == other.graph_;
1229 }
1230 
1231 // Since the GridGraph has no backing storage for each of the Adjacency
1232 // objects handled in the class, the AdjacencyIterator is limited to only
1233 // one adjacency object per iterator instance.
1234 // This should be sufficient for most normal usage scenarios, and is supported
1235 // by the very lightweight copying of the AdjacencyType object itself.
1236 // Note, however, that if you store a reference to the pointed object,
1237 // then advance the iterator and subsequently dereference it again,
1238 // the new reference will refer to the very same same adjacency object,
1239 // unique for the AdjacencyIterator instance.
1240 // This operation will therefore silently update all previous references to
1241 // the adjacency object of the iterator.
1242 template<unsigned char D, class VISITOR>
1243 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::reference
1244 GridGraph<D, VISITOR>::AdjacencyIterator::operator*() {
1245  adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_);
1246  return adjacency_;
1247 }
1248 
1249 template<unsigned char D, class VISITOR>
1250 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::pointer
1251 GridGraph<D, VISITOR>::AdjacencyIterator::operator->() {
1252  adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_);
1253  return &adjacency_;
1254 }
1255 
1256 template<unsigned char D, class VISITOR>
1257 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::reference
1258 GridGraph<D, VISITOR>::AdjacencyIterator::operator[](
1259  const difference_type j
1260 ) {
1261  adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_ + j);
1262  return adjacency_;
1263 }
1264 
1265 // implementation of VertexIterator
1266 
1267 template<unsigned char D, class VISITOR>
1268 inline
1269 GridGraph<D, VISITOR>::VertexIterator::VertexIterator()
1270  : Base()
1271 {}
1272 
1273 template<unsigned char D, class VISITOR>
1274 inline
1275 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1276  const GraphType& graph
1277 )
1278  : Base(graph)
1279 {}
1280 
1281 template<unsigned char D, class VISITOR>
1282 inline
1283 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1284  const GraphType& graph,
1285  const size_type vertex
1286 )
1287  : Base(graph, vertex)
1288 {}
1289 
1290 template<unsigned char D, class VISITOR>
1291 inline
1292 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1293  const GraphType& graph,
1294  const size_type vertex,
1295  const size_type adjacencyIndex
1296 )
1297  : Base(graph, vertex, adjacencyIndex)
1298 {}
1299 
1300 template<unsigned char D, class VISITOR>
1301 inline
1302 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1303  const VertexIterator& it
1304 )
1305  : Base(*(it.graph_), it.vertex_, it.adjacencyIndex_)
1306 {}
1307 
1308 template<unsigned char D, class VISITOR>
1309 inline
1310 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1311  const AdjacencyIterator& it
1312 )
1313  : Base(it)
1314 {}
1315 
1316 template<unsigned char D, class VISITOR>
1317 inline typename GridGraph<D, VISITOR>::VertexIterator::value_type
1318 GridGraph<D, VISITOR>::VertexIterator::operator*() const {
1319  return Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_);
1320 }
1321 
1322 template<unsigned char D, class VISITOR>
1323 inline typename GridGraph<D, VISITOR>::VertexIterator::value_type
1324 GridGraph<D, VISITOR>::VertexIterator::operator[](
1325  const difference_type j
1326 ) const {
1327  return Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_ + j);
1328 }
1329 
1330 template<unsigned char D, class VISITOR>
1331 inline void
1332 GridGraph<D, VISITOR>::VertexIterator::coordinate(
1333  VertexCoordinate& vertexCoordinate
1334 ) const {
1335  const size_type opposite = Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_);
1336  Base::graph_->vertex(opposite, vertexCoordinate);
1337 }
1338 
1339 // implementation of EdgeIterator
1340 
1341 template<unsigned char D, class VISITOR>
1342 inline
1343 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator()
1344  : Base()
1345 {}
1346 
1347 template<unsigned char D, class VISITOR>
1348 inline
1349 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1350  const GraphType& graph
1351 )
1352  : Base(graph)
1353 {}
1354 
1355 template<unsigned char D, class VISITOR>
1356 inline
1357 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1358  const GraphType& graph,
1359  const size_type vertex
1360 )
1361  : Base(graph, vertex)
1362 {}
1363 
1364 template<unsigned char D, class VISITOR>
1365 inline
1366 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1367  const GraphType& graph,
1368  const size_type vertex,
1369  const size_type adjacencyIndex
1370 )
1371  : Base(graph, vertex, adjacencyIndex)
1372 {}
1373 
1374 template<unsigned char D, class VISITOR>
1375 inline
1376 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1377  const EdgeIterator& it
1378 )
1379  : Base(*(it.graph_), it.vertex_, it.adjacencyIndex_)
1380 {}
1381 
1382 template<unsigned char D, class VISITOR>
1383 inline
1384 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1385  const AdjacencyIterator& it
1386 )
1387  : Base(it)
1388 {}
1389 
1390 template<unsigned char D, class VISITOR>
1391 inline typename GridGraph<D, VISITOR>::EdgeIterator::value_type
1392 GridGraph<D, VISITOR>::EdgeIterator::operator*() const {
1393  return Base::graph_->edgeFromVertex(Base::vertex_, Base::adjacencyIndex_);
1394 }
1395 
1396 template<unsigned char D, class VISITOR>
1397 inline typename GridGraph<D, VISITOR>::EdgeIterator::value_type
1398 GridGraph<D, VISITOR>::EdgeIterator::operator[](
1399  const difference_type j
1400 ) const {
1401  return Base::graph_->edgeFromVertex(Base::vertex_, Base::adjacencyIndex_ + j);
1402 }
1403 
1404 // \endcond
1405 
1406 
1407 } // namespace graph
1408 } // namespace andres
1409 
1410 #endif // #ifndef ANDRES_GRAPH_GRID_GRAPH_HXX
1411 
1412