Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
00017 #define GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
00018
00019 #include "gui/auxiliary/iterator/exception.hpp"
00020 #include "gui/auxiliary/iterator/policy_visit.hpp"
00021 #include "gui/auxiliary/log.hpp"
00022 #include "gui/widgets/widget.hpp"
00023
00024 #include <iostream>
00025
00026 namespace gui2 {
00027
00028 namespace iterator {
00029
00030 namespace policy {
00031
00032 namespace order {
00033
00034 template<
00035 bool visit_widget
00036 , bool visit_grid
00037 , bool visit_child
00038 >
00039 class tbottom_up
00040 : public tvisit<visit_widget, twalker_::widget>
00041 , public tvisit<visit_grid, twalker_::grid>
00042 , public tvisit<visit_child, twalker_::child>
00043 {
00044 typedef tvisit<visit_widget, twalker_::widget> tvisit_widget;
00045 typedef tvisit<visit_grid, twalker_::grid> tvisit_grid;
00046 typedef tvisit<visit_child, twalker_::child> tvisit_child;
00047 public:
00048 explicit tbottom_up(twidget& root)
00049 : root_(root.create_walker())
00050 , stack_()
00051 {
00052 TST_GUI_I << "Constructor: ";
00053 while(!tvisit_child::at_end(*root_)) {
00054 stack_.push_back(root_);
00055 root_ = tvisit_child::get(*root_)->create_walker();
00056 TST_GUI_I << " Down widget '" << operator*().id() << "'.";
00057 }
00058
00059 if(!at_end()) {
00060 TST_GUI_I << " Finished at '" << operator*().id() << "'.\n";
00061 } else {
00062 TST_GUI_I << " Finished at the end.\n";
00063 }
00064 }
00065
00066 ~tbottom_up()
00067 {
00068 delete root_;
00069 for(std::vector<iterator::twalker_*>::iterator itor = stack_.begin()
00070 ; itor != stack_.end()
00071 ; ++itor) {
00072
00073 delete *itor;
00074 }
00075 }
00076
00077 bool at_end() const
00078 {
00079 return tvisit_widget::at_end(*root_)
00080 && tvisit_grid::at_end(*root_)
00081 && tvisit_child::at_end(*root_);
00082 }
00083
00084 bool next()
00085 {
00086 if(at_end()) {
00087 ERR_GUI_I << "Tried to move beyond end of the iteration range.\n";
00088 throw trange_error("Tried to move beyond end of range.");
00089 }
00090
00091 TST_GUI_I << "At '" << operator*().id() << "'.";
00092
00093
00094 TST_GUI_I << " Iterate widget:";
00095 if(!tvisit_widget::at_end(*root_)) {
00096 switch(tvisit_widget::next(*root_)) {
00097 case twalker_::valid :
00098 TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00099 return true;
00100 case twalker_::invalid :
00101 TST_GUI_I << " reached the end.";
00102 break;
00103 case twalker_::fail:
00104 TST_GUI_I << "\n";
00105 ERR_GUI_E << "Tried to move beyond end of "
00106 "the widget iteration range.\n";
00107 throw trange_error("Tried to move beyond end of range.");
00108 }
00109 } else {
00110 TST_GUI_I << " failed.";
00111 }
00112
00113
00114 TST_GUI_I << " Iterate grid:";
00115 if(!tvisit_grid::at_end(*root_)) {
00116 switch(tvisit_grid::next(*root_)) {
00117 case twalker_::valid :
00118 TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00119 return true;
00120 case twalker_::invalid :
00121 TST_GUI_I << " reached the end.";
00122 break;
00123 case twalker_::fail:
00124 TST_GUI_I << "\n";
00125 ERR_GUI_E << "Tried to move beyond end of "
00126 "the grid iteration range.\n";
00127 throw trange_error("Tried to move beyond end of range.");
00128 }
00129 } else {
00130 TST_GUI_I << " failed.";
00131 }
00132
00133
00134
00135 TST_GUI_I << " Iterate child:";
00136 if(tvisit_child::at_end(*root_)) {
00137 if(stack_.empty()) {
00138 TST_GUI_I << " Finished iteration.\n";
00139 return false;
00140 } else {
00141 delete root_;
00142
00143 root_ = stack_.back();
00144 stack_.pop_back();
00145 TST_GUI_I << " Up '" << operator*().id() << "'.";
00146 }
00147 }
00148 TST_GUI_I << " Iterate child:";
00149 if(!tvisit_child::at_end(*root_)) {
00150 switch(tvisit_child::next(*root_)) {
00151 case twalker_::valid :
00152 TST_GUI_I << " visit '" << operator*().id() << "'.";
00153 break;
00154 case twalker_::invalid :
00155 TST_GUI_I << " reached the end.";
00156 break;
00157 case twalker_::fail:
00158 TST_GUI_I << "\n";
00159 ERR_GUI_E << "Tried to move beyond end of "
00160 "the child iteration range.\n";
00161 throw trange_error("Tried to move beyond end of range.");
00162 }
00163 } else {
00164 TST_GUI_I << " already at the end.";
00165 }
00166
00167 while(!tvisit_child::at_end(*root_)) {
00168 stack_.push_back(root_);
00169 root_ = tvisit_child::get(*root_)->create_walker();
00170 TST_GUI_I << " Down widget '"
00171 << operator*().id() << "'.";
00172 }
00173 TST_GUI_I << " Visit '" << operator*().id() << "'.\n";
00174 return true;
00175 }
00176
00177 twidget& operator*()
00178 {
00179 if(at_end()) {
00180 ERR_GUI_I << "Tried to defer beyond end its "
00181 "iteration range iterator.\n";
00182 throw tlogic_error("Tried to defer an invalid iterator.");
00183 }
00184 if(!tvisit_widget::at_end(*root_)) {
00185 return *tvisit_widget::get(*root_);
00186 }
00187 if(!tvisit_grid::at_end(*root_)) {
00188 return *tvisit_grid::get(*root_);
00189 }
00190 if(!tvisit_child::at_end(*root_)) {
00191 return *tvisit_child::get(*root_);
00192 }
00193 ERR_GUI_I << "The iterator ended in an unknown "
00194 "state while deferring iteself.\n";
00195 throw tlogic_error("Tried to defer an invalid iterator.");
00196 }
00197
00198 private:
00199
00200 iterator::twalker_* root_;
00201
00202 std::vector<iterator::twalker_*> stack_;
00203 };
00204
00205 template<
00206 bool visit_widget
00207 , bool visit_grid
00208 , bool visit_child
00209 >
00210 class ttop_down
00211 : public tvisit<visit_widget, twalker_::widget>
00212 , public tvisit<visit_grid, twalker_::grid>
00213 , public tvisit<visit_child, twalker_::child>
00214 {
00215 typedef tvisit<visit_widget, twalker_::widget> tvisit_widget;
00216 typedef tvisit<visit_grid, twalker_::grid> tvisit_grid;
00217 typedef tvisit<visit_child, twalker_::child> tvisit_child;
00218 public:
00219 explicit ttop_down (twidget& root)
00220 : root_(root.create_walker())
00221 , stack_()
00222 {
00223 }
00224
00225 ~ttop_down()
00226 {
00227 delete root_;
00228 for(std::vector<iterator::twalker_*>::iterator itor = stack_.begin()
00229 ; itor != stack_.end()
00230 ; ++itor) {
00231
00232 delete *itor;
00233 }
00234 }
00235
00236 bool at_end() const
00237 {
00238 return tvisit_widget::at_end(*root_)
00239 && tvisit_grid::at_end(*root_)
00240 && tvisit_child::at_end(*root_);
00241 }
00242
00243 bool next()
00244 {
00245 if(at_end()) {
00246 ERR_GUI_I << "Tried to move beyond end of the iteration range.\n";
00247 throw trange_error("Tried to move beyond end of range.");
00248 }
00249
00250 TST_GUI_I << "At '" << operator*().id() << "'.";
00251
00252
00253 TST_GUI_I << " Iterate widget:";
00254 if(!tvisit_widget::at_end(*root_)) {
00255 switch(tvisit_widget::next(*root_)) {
00256 case twalker_::valid :
00257 TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00258 return true;
00259 case twalker_::invalid :
00260 TST_GUI_I << " reached the end.";
00261 break;
00262 case twalker_::fail:
00263 TST_GUI_I << "\n";
00264 ERR_GUI_E << "Tried to move beyond end of the "
00265 "widget iteration range.\n";
00266 throw trange_error("Tried to move beyond end of range.");
00267 }
00268 } else {
00269 TST_GUI_I << " failed.";
00270 }
00271
00272
00273 TST_GUI_I << " Iterate grid:";
00274 if(!tvisit_grid::at_end(*root_)) {
00275 switch(tvisit_grid::next(*root_)) {
00276 case twalker_::valid :
00277 TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00278 return true;
00279 case twalker_::invalid :
00280 TST_GUI_I << " reached the end.";
00281 break;
00282 case twalker_::fail:
00283 TST_GUI_I << "\n";
00284 ERR_GUI_E << "Tried to move beyond end of the grid "
00285 "iteration range.\n";
00286 throw trange_error("Tried to move beyond end of range.");
00287 }
00288 } else {
00289 TST_GUI_I << " failed.";
00290 }
00291
00292
00293
00294 TST_GUI_I << " Iterate child:";
00295 if(tvisit_child::at_end(*root_)) {
00296 TST_GUI_I << " reached the end.";
00297 up();
00298 } else {
00299 TST_GUI_I << " proceed.";
00300 }
00301
00302 if(!tvisit_child::at_end(*root_)) {
00303 stack_.push_back(root_);
00304 root_ = tvisit_child::get(*root_)->create_walker();
00305
00306 assert(root_);
00307 assert(!at_end());
00308 TST_GUI_I << " Down and visit '" << operator*().id() << "'.\n";
00309 return true;
00310 }
00311
00312 TST_GUI_I << " Finished iteration.\n";
00313 return false;
00314 }
00315
00316 twidget& operator*()
00317 {
00318 if(at_end()) {
00319 ERR_GUI_I << "Tried to defer beyond end of the iteration "
00320 "range iterator.\n";
00321 throw tlogic_error("Tried to defer an invalid iterator.");
00322 }
00323 if(!tvisit_widget::at_end(*root_)) {
00324 return *tvisit_widget::get(*root_);
00325 }
00326 if(!tvisit_grid::at_end(*root_)) {
00327 return *tvisit_grid::get(*root_);
00328 }
00329 if(!tvisit_child::at_end(*root_)) {
00330 return *tvisit_child::get(*root_);
00331 }
00332 ERR_GUI_I << "The iterator ended in an unknown "
00333 "state while deferring iteself.\n";
00334 throw tlogic_error("Tried to defer an invalid iterator.");
00335 }
00336
00337 private:
00338
00339 bool up()
00340 {
00341 while(!stack_.empty()) {
00342 delete root_;
00343
00344 root_ = stack_.back();
00345 stack_.pop_back();
00346 TST_GUI_I << " Up widget '" << operator*().id() << "'. Iterate:";
00347 switch(tvisit_child::next(*root_)) {
00348 case twalker_::valid:
00349 TST_GUI_I << " reached '" << operator*().id() << "'.";
00350 return true;
00351 case twalker_::invalid:
00352 TST_GUI_I << " failed.";
00353 break;
00354 case twalker_::fail:
00355 throw trange_error("Tried to move beyond end of range.");
00356 }
00357 }
00358 return true;
00359 }
00360
00361 iterator::twalker_* root_;
00362
00363 std::vector<iterator::twalker_*> stack_;
00364 };
00365
00366 }
00367
00368 }
00369
00370 }
00371
00372 }
00373
00374 #endif
00375
00376