mesh_graph_generator.hpp 5.5 KB

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