Chris@16
|
1 // Copyright 2004, 2005 The Trustees of Indiana University.
|
Chris@16
|
2
|
Chris@16
|
3 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6
|
Chris@16
|
7 // Authors: Nick Edmonds
|
Chris@16
|
8 // Andrew Lumsdaine
|
Chris@16
|
9 #ifndef BOOST_GRAPH_MESH_GENERATOR_HPP
|
Chris@16
|
10 #define BOOST_GRAPH_MESH_GENERATOR_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #include <iterator>
|
Chris@16
|
13 #include <utility>
|
Chris@16
|
14 #include <boost/assert.hpp>
|
Chris@16
|
15 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
16 #include <boost/type_traits/is_base_and_derived.hpp>
|
Chris@16
|
17 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost {
|
Chris@16
|
20
|
Chris@16
|
21 template<typename Graph>
|
Chris@16
|
22 class mesh_iterator
|
Chris@16
|
23 {
|
Chris@16
|
24 typedef typename graph_traits<Graph>::directed_category directed_category;
|
Chris@16
|
25 typedef typename graph_traits<Graph>::vertices_size_type
|
Chris@16
|
26 vertices_size_type;
|
Chris@16
|
27
|
Chris@16
|
28 BOOST_STATIC_CONSTANT
|
Chris@16
|
29 (bool,
|
Chris@16
|
30 is_undirected = (is_base_and_derived<undirected_tag,
|
Chris@16
|
31 directed_category>::value
|
Chris@16
|
32 || is_same<undirected_tag, directed_category>::value));
|
Chris@16
|
33
|
Chris@16
|
34 public:
|
Chris@16
|
35 typedef std::input_iterator_tag iterator_category;
|
Chris@16
|
36 typedef std::pair<vertices_size_type, vertices_size_type> value_type;
|
Chris@16
|
37 typedef const value_type& reference;
|
Chris@16
|
38 typedef const value_type* pointer;
|
Chris@16
|
39 typedef void difference_type;
|
Chris@16
|
40
|
Chris@16
|
41 mesh_iterator()
|
Chris@16
|
42 : x(0), y(0), done(true) { }
|
Chris@16
|
43
|
Chris@16
|
44 // Vertices are numbered in row-major order
|
Chris@16
|
45 // Assumes directed
|
Chris@16
|
46 mesh_iterator(vertices_size_type x, vertices_size_type y,
|
Chris@16
|
47 bool toroidal = true)
|
Chris@16
|
48 : x(x), y(y), n(x*y), source(0), target(1), current(0,1),
|
Chris@16
|
49 toroidal(toroidal), done(false)
|
Chris@16
|
50 { BOOST_ASSERT(x > 1 && y > 1); }
|
Chris@16
|
51
|
Chris@16
|
52 reference operator*() const { return current; }
|
Chris@16
|
53 pointer operator->() const { return ¤t; }
|
Chris@16
|
54
|
Chris@16
|
55 mesh_iterator& operator++()
|
Chris@16
|
56 {
|
Chris@16
|
57 if (is_undirected) {
|
Chris@16
|
58 if (!toroidal) {
|
Chris@16
|
59 if (target == source + 1)
|
Chris@16
|
60 if (source < x * (y - 1))
|
Chris@16
|
61 target = source + x;
|
Chris@16
|
62 else {
|
Chris@16
|
63 source++;
|
Chris@16
|
64 target = (source % x) < x - 1 ? source + 1 : source + x;
|
Chris@16
|
65 if (target > n)
|
Chris@16
|
66 done = true;
|
Chris@16
|
67 }
|
Chris@16
|
68 else if (target == source + x) {
|
Chris@16
|
69 source++;
|
Chris@16
|
70 target = (source % x) < x - 1 ? source + 1 : source + x;
|
Chris@16
|
71 }
|
Chris@16
|
72 } else {
|
Chris@16
|
73 if (target == source + 1 || target == source - (source % x))
|
Chris@16
|
74 target = (source + x) % n;
|
Chris@16
|
75 else if (target == (source + x) % n) {
|
Chris@16
|
76 if (source == n - 1)
|
Chris@16
|
77 done = true;
|
Chris@16
|
78 else {
|
Chris@16
|
79 source++;
|
Chris@16
|
80 target = (source % x) < (x - 1) ? source + 1 : source - (source % x);
|
Chris@16
|
81 }
|
Chris@16
|
82 }
|
Chris@16
|
83 }
|
Chris@16
|
84 } else { // Directed
|
Chris@16
|
85 if ( !toroidal ) {
|
Chris@16
|
86 if (target == source - x)
|
Chris@16
|
87 target = source % x > 0 ? source - 1 : source + 1;
|
Chris@16
|
88 else if (target == source - 1)
|
Chris@16
|
89 if ((source % x) < (x - 1))
|
Chris@16
|
90 target = source + 1;
|
Chris@16
|
91 else if (source < x * (y - 1))
|
Chris@16
|
92 target = source + x;
|
Chris@16
|
93 else {
|
Chris@16
|
94 done = true;
|
Chris@16
|
95 }
|
Chris@16
|
96 else if (target == source + 1)
|
Chris@16
|
97 if (source < x * (y - 1))
|
Chris@16
|
98 target = source + x;
|
Chris@16
|
99 else {
|
Chris@16
|
100 source++;
|
Chris@16
|
101 target = source - x;
|
Chris@16
|
102 }
|
Chris@16
|
103 else if (target == source + x) {
|
Chris@16
|
104 source++;
|
Chris@16
|
105 target = (source >= x) ? source - x : source - 1;
|
Chris@16
|
106 }
|
Chris@16
|
107 } else {
|
Chris@16
|
108 if (source == n - 1 && target == (source + x) % n)
|
Chris@16
|
109 done = true;
|
Chris@16
|
110 else if (target == source - 1 || target == source + x - 1)
|
Chris@16
|
111 target = (source + x) % n;
|
Chris@16
|
112 else if (target == source + 1 || target == source - (source % x))
|
Chris@16
|
113 target = (source - x + n) % n;
|
Chris@16
|
114 else if (target == (source - x + n) % n)
|
Chris@16
|
115 target = (source % x > 0) ? source - 1 : source + x - 1;
|
Chris@16
|
116 else if (target == (source + x) % n) {
|
Chris@16
|
117 source++;
|
Chris@16
|
118 target = (source % x) < (x - 1) ? source + 1 : source - (source % x);
|
Chris@16
|
119 }
|
Chris@16
|
120 }
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 current.first = source;
|
Chris@16
|
124 current.second = target;
|
Chris@16
|
125
|
Chris@16
|
126 return *this;
|
Chris@16
|
127 }
|
Chris@16
|
128
|
Chris@16
|
129 mesh_iterator operator++(int)
|
Chris@16
|
130 {
|
Chris@16
|
131 mesh_iterator temp(*this);
|
Chris@16
|
132 ++(*this);
|
Chris@16
|
133 return temp;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 bool operator==(const mesh_iterator& other) const
|
Chris@16
|
137 {
|
Chris@16
|
138 return done == other.done;
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 bool operator!=(const mesh_iterator& other) const
|
Chris@16
|
142 { return !(*this == other); }
|
Chris@16
|
143
|
Chris@16
|
144 private:
|
Chris@16
|
145
|
Chris@16
|
146 vertices_size_type x,y;
|
Chris@16
|
147 vertices_size_type n;
|
Chris@16
|
148 vertices_size_type source;
|
Chris@16
|
149 vertices_size_type target;
|
Chris@16
|
150 value_type current;
|
Chris@16
|
151 bool toroidal;
|
Chris@16
|
152 bool done;
|
Chris@16
|
153 };
|
Chris@16
|
154
|
Chris@16
|
155
|
Chris@16
|
156 } // end namespace boost
|
Chris@16
|
157
|
Chris@16
|
158 #endif // BOOST_GRAPH_MESH_GENERATOR_HPP
|