mesh_graph_generator.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. template<typename Graph>
  17. class mesh_iterator
  18. {
  19. typedef typename graph_traits<Graph>::directed_category directed_category;
  20. typedef typename graph_traits<Graph>::vertices_size_type
  21. vertices_size_type;
  22. BOOST_STATIC_CONSTANT
  23. (bool,
  24. is_undirected = (is_base_and_derived<undirected_tag,
  25. directed_category>::value
  26. || is_same<undirected_tag, directed_category>::value));
  27. public:
  28. typedef std::input_iterator_tag iterator_category;
  29. typedef std::pair<vertices_size_type, vertices_size_type> value_type;
  30. typedef const value_type& reference;
  31. typedef const value_type* pointer;
  32. typedef void difference_type;
  33. mesh_iterator()
  34. : x(0), y(0), done(true) { }
  35. // Vertices are numbered in row-major order
  36. // Assumes directed
  37. mesh_iterator(vertices_size_type x, vertices_size_type y,
  38. bool toroidal = true)
  39. : x(x), y(y), n(x*y), source(0), target(1), current(0,1),
  40. toroidal(toroidal), done(false)
  41. { BOOST_ASSERT(x > 1 && y > 1); }
  42. reference operator*() const { return current; }
  43. pointer operator->() const { return &current; }
  44. mesh_iterator& operator++()
  45. {
  46. if (is_undirected) {
  47. if (!toroidal) {
  48. if (target == source + 1)
  49. if (source < x * (y - 1))
  50. target = source + x;
  51. else {
  52. source++;
  53. target = (source % x) < x - 1 ? source + 1 : source + x;
  54. if (target > n)
  55. done = true;
  56. }
  57. else if (target == source + x) {
  58. source++;
  59. target = (source % x) < x - 1 ? source + 1 : source + x;
  60. }
  61. } else {
  62. if (target == source + 1 || target == source - (source % x))
  63. target = (source + x) % n;
  64. else if (target == (source + x) % n) {
  65. if (source == n - 1)
  66. done = true;
  67. else {
  68. source++;
  69. target = (source % x) < (x - 1) ? source + 1 : source - (source % x);
  70. }
  71. }
  72. }
  73. } else { // Directed
  74. if ( !toroidal ) {
  75. if (target == source - x)
  76. target = source % x > 0 ? source - 1 : source + 1;
  77. else if (target == source - 1)
  78. if ((source % x) < (x - 1))
  79. target = source + 1;
  80. else if (source < x * (y - 1))
  81. target = source + x;
  82. else {
  83. done = true;
  84. }
  85. else if (target == source + 1)
  86. if (source < x * (y - 1))
  87. target = source + x;
  88. else {
  89. source++;
  90. target = source - x;
  91. }
  92. else if (target == source + x) {
  93. source++;
  94. target = (source >= x) ? source - x : source - 1;
  95. }
  96. } else {
  97. if (source == n - 1 && target == (source + x) % n)
  98. done = true;
  99. else if (target == source - 1 || target == source + x - 1)
  100. target = (source + x) % n;
  101. else if (target == source + 1 || target == source - (source % x))
  102. target = (source - x + n) % n;
  103. else if (target == (source - x + n) % n)
  104. target = (source % x > 0) ? source - 1 : source + x - 1;
  105. else if (target == (source + x) % n) {
  106. source++;
  107. target = (source % x) < (x - 1) ? source + 1 : source - (source % x);
  108. }
  109. }
  110. }
  111. current.first = source;
  112. current.second = target;
  113. return *this;
  114. }
  115. mesh_iterator operator++(int)
  116. {
  117. mesh_iterator temp(*this);
  118. ++(*this);
  119. return temp;
  120. }
  121. bool operator==(const mesh_iterator& other) const
  122. {
  123. return done == other.done;
  124. }
  125. bool operator!=(const mesh_iterator& other) const
  126. { return !(*this == other); }
  127. private:
  128. vertices_size_type x,y;
  129. vertices_size_type n;
  130. vertices_size_type source;
  131. vertices_size_type target;
  132. value_type current;
  133. bool toroidal;
  134. bool done;
  135. };
  136. } // end namespace boost
  137. #endif // BOOST_GRAPH_MESH_GENERATOR_HPP