00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00028 # define MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00029
00033
00034 # include <vector>
00035 # include <mln/core/concept/browsing.hh>
00036
00037
00038 namespace mln
00039 {
00040
00041 namespace canvas
00042 {
00043
00044 namespace browsing
00045 {
00046
00048
00076 struct snake_generic_t : public Browsing< snake_generic_t >
00077 {
00078
00079
00080
00081 snake_generic_t();
00082
00083 template <typename F>
00084 void operator()(F& f) const;
00085
00086 };
00087
00088 extern const snake_generic_t snake_generic;
00089
00090 # ifndef MLN_INCLUDE_ONLY
00091
00092 # ifndef MLN_WO_GLOBAL_VARS
00093
00094 const snake_generic_t snake_generic;
00095
00096 # endif // ! MLN_WO_GLOBAL_VARS
00097
00098 inline
00099 snake_generic_t::snake_generic_t()
00100 {
00101 }
00102
00103 template <typename F>
00104 inline
00105 void
00106 snake_generic_t::operator()(F& f) const
00107 {
00108 trace::entering("canvas::browsing::snake_generic");
00109 mln_precondition(f.input.is_valid());
00110
00111
00112 f.p = f.input.bbox().pmin();
00113
00114 std::vector< int > directions(f.moves.size(), 0);
00115 unsigned deph = 0;
00116 unsigned total_deph = f.moves.size() / 2 + 1;
00117
00118
00119 f.init();
00120
00121 bool first = true;
00122 directions[deph] = 1;
00123 deph = total_deph - 1;
00124
00125
00126 (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00127 while (deph > 0)
00128 {
00129 mln_assertion(deph <= total_deph);
00130 mln_assertion(deph > 0);
00131
00132 if (!f.input.domain().has(f.p +
00133 f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]]))
00134 {
00135
00136 deph--;
00137 if (deph >= 1)
00138
00139 directions[deph] = directions[deph] == 1 ? 0 : 1;
00140 continue;
00141 }
00142
00143 if (!first)
00144 {
00145
00146 f.p += f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]];
00147
00148 (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00149 }
00150 else
00151 first = false;
00152
00153 if (deph != total_deph)
00154 {
00155
00156 deph++;
00157 first = true;
00158 }
00159 }
00160
00161 trace::exiting("canvas::browsing::snake_generic");
00162 }
00163
00164 # endif // ! MLN_INCLUDE_ONLY
00165
00166 }
00167
00168 }
00169
00170 }
00171
00172
00173 #endif // ! MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH