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
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef ESBTL_ITERATORS_H
00036 #define ESBTL_ITERATORS_H
00037
00038 #include <boost/iterator/iterator_facade.hpp>
00039
00040 namespace ESBTL{
00042 namespace internal{
00043
00044 template <class T,bool b>
00045 struct do_add_const_to_ref;
00046
00047 template <class T>
00048 struct do_add_const_to_ref<T,true>{typedef const T& type;};
00049
00050 template <class T>
00051 struct do_add_const_to_ref<T,false>{typedef T& type;};
00052
00053 template <class T,bool b>
00054 struct do_add_const;
00055
00056 template <class T>
00057 struct do_add_const<T,true>{typedef const T type;};
00058
00059 template <class T>
00060 struct do_add_const<T,false>{typedef T type;};
00061
00062
00063 template <class T,bool b>
00064 struct do_add_const_to_ptr;
00065
00066 template <class T>
00067 struct do_add_const_to_ptr<T,true>{typedef const T* type;};
00068
00069 template <class T>
00070 struct do_add_const_to_ptr<T,false>{typedef T* type;};
00071
00072
00073 template <class T,bool b>
00074 struct do_get_const_iterator;
00075
00076 template <class T>
00077 struct do_get_const_iterator<T,true>{typedef typename T::const_iterator type;};
00078
00079 template <class T>
00080 struct do_get_const_iterator<T,false>{typedef typename T::iterator type;};
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 template <class Model,bool is_const>
00097 class Chains_iterator_from_model:
00098 public boost::iterator_facade<
00099 Chains_iterator_from_model<Model,is_const>,
00100 typename do_add_const<typename Model::Chain,is_const>::type,
00101 boost::forward_traversal_tag>
00102 {
00103 private:
00104 typedef typename Model::System::Chain Chain;
00105 public:
00106 Chains_iterator_from_model(typename do_get_const_iterator<typename Model::Chain_container,is_const>::type it):
00107 chain_it(it){}
00108
00109 private:
00110 friend class boost::iterator_core_access;
00111
00112 void increment(){++chain_it;}
00113 bool equal(Chains_iterator_from_model const& other) const{ return other.chain_it==chain_it; }
00114 typename do_add_const_to_ref<Chain,is_const>::type dereference() const {return Model::dereference(chain_it);}
00115
00116
00117 typename do_get_const_iterator<typename Model::Chain_container,is_const>::type chain_it;
00118 };
00119
00120
00121 template <class Chain,bool is_const>
00122 class Residues_iterator_from_chain:
00123 public boost::iterator_facade<
00124 Residues_iterator_from_chain<Chain,is_const>,
00125 typename do_add_const<typename Chain::Residue,is_const>::type,
00126 boost::forward_traversal_tag>
00127 {
00128 private:
00129 typedef typename Chain::Residue Residue;
00130 public:
00131 Residues_iterator_from_chain(typename do_get_const_iterator<typename Chain::Residue_container,is_const>::type it):
00132 res_it(it){}
00133 Residues_iterator_from_chain(){}
00134 private:
00135 friend class boost::iterator_core_access;
00136
00137 void increment(){++res_it;}
00138 bool equal(Residues_iterator_from_chain const& other) const{ return other.res_it==res_it; }
00139 typename do_add_const_to_ref<Residue,is_const>::type dereference() const {return Chain::dereference(res_it);}
00140
00141
00142 typename do_get_const_iterator<typename Chain::Residue_container,is_const>::type res_it;
00143 };
00144
00145
00146 template <class Model,bool is_const>
00147 class Residues_iterator_from_model:
00148 public boost::iterator_facade<
00149 Residues_iterator_from_model<Model,is_const>,
00150 typename do_add_const<typename Model::Chain::Residue,is_const>::type,
00151 boost::forward_traversal_tag>
00152 {
00153 private:
00154 typedef typename Model::Chain::Residue Residue;
00155 Chains_iterator_from_model<Model,is_const> chain_it;
00156 Chains_iterator_from_model<Model,is_const> chain_end;
00157 Residues_iterator_from_chain<typename Model::Chain,is_const> res_it;
00158 Residues_iterator_from_chain<typename Model::Chain,is_const> res_end;
00159 public:
00160 Residues_iterator_from_model(typename do_add_const_to_ref<Model,is_const>::type model,bool is_end=false):
00161 chain_it(is_end?model.chains_end():model.chains_begin()),chain_end(model.chains_end())
00162 {
00163 if (chain_it!=chain_end){
00164 res_it=chain_it->residues_begin();
00165 res_end=chain_it->residues_end();
00166 }
00167 }
00168 private:
00169 friend class boost::iterator_core_access;
00170
00171 void increment(){
00172 ++res_it;
00173 if (res_it==res_end){
00174 do{
00175 ++chain_it;
00176 if (chain_it!=chain_end){
00177 res_it=chain_it->residues_begin();
00178 res_end=chain_it->residues_end();
00179 }
00180 else{break;}
00181 }while (res_it==res_end);
00182 }
00183 }
00184 bool equal(Residues_iterator_from_model const& other) const{
00185 return chain_it==other.chain_it && ( chain_it==chain_end || other.res_it==res_it );
00186 }
00187 typename do_add_const_to_ref<Residue,is_const>::type dereference() const {return *res_it;}
00188 };
00189
00190
00191 template <class Residue,bool is_const>
00192 class Atoms_iterator_from_residue:
00193 public boost::iterator_facade<
00194 Atoms_iterator_from_residue<Residue,is_const>,
00195 typename do_add_const<typename Residue::Atom,is_const>::type,
00196 boost::forward_traversal_tag>
00197 {
00198 private:
00199 typedef typename Residue::Atom Atom;
00200 public:
00201
00202 Atoms_iterator_from_residue(typename do_get_const_iterator<typename Residue::Atom_container,is_const>::type it):
00203 atm_it(it),atm_end(it){}
00204
00205 Atoms_iterator_from_residue(
00206 typename do_get_const_iterator<typename Residue::Atom_container,is_const>::type it,
00207 typename do_get_const_iterator<typename Residue::Atom_container,is_const>::type end
00208 ):atm_it(it),atm_end(end)
00209 {}
00210
00211 Atoms_iterator_from_residue(){}
00212 private:
00213 friend class boost::iterator_core_access;
00214
00215 void increment(){
00216 ++atm_it;
00217 }
00218
00219 bool equal(Atoms_iterator_from_residue const& other) const{ return other.atm_it==atm_it; }
00220 typename do_add_const_to_ref<Atom,is_const>::type dereference() const {return Residue::dereference(atm_it);}
00221
00222
00223 typename do_get_const_iterator<typename Residue::Atom_container,is_const>::type atm_it;
00224 typename do_get_const_iterator<typename Residue::Atom_container,is_const>::type atm_end;
00225 };
00226
00227
00228 template <class Chain,bool is_const>
00229 class Atoms_iterator_from_chain:
00230 public boost::iterator_facade<
00231 Atoms_iterator_from_chain<Chain,is_const>,
00232 typename do_add_const<typename Chain::Residue::Atom,is_const>::type,
00233 boost::forward_traversal_tag>
00234 {
00235 private:
00236 typedef typename Chain::Residue::Atom Atom;
00237
00238 Residues_iterator_from_chain<Chain,is_const> res_it;
00239 Residues_iterator_from_chain<Chain,is_const> res_end;
00240 Atoms_iterator_from_residue<typename Chain::Residue,is_const> atm_it;
00241 Atoms_iterator_from_residue<typename Chain::Residue,is_const> atm_end;
00242 public:
00243 Atoms_iterator_from_chain(){}
00244 Atoms_iterator_from_chain(typename do_add_const_to_ref<Chain,is_const>::type chain,bool is_end=false):
00245 res_it(is_end?chain.residues_end():chain.residues_begin()),res_end(chain.residues_end())
00246 {
00247 if (res_it!=res_end){
00248 atm_it=res_it->atoms_begin();
00249 atm_end=res_it->atoms_end();
00250 make_valid();
00251 }
00252 }
00253 private:
00254 friend class boost::iterator_core_access;
00255
00256 void increment(){
00257 ++atm_it;
00258 make_valid();
00259 }
00260
00261 void make_valid(){
00262 while(atm_it==atm_end){
00263 ++res_it;
00264 if (res_it==res_end) break;
00265 atm_it=res_it->atoms_begin();
00266 atm_end=res_it->atoms_end();
00267 }
00268 }
00269
00270 bool equal(Atoms_iterator_from_chain const& other) const{
00271 return res_it==other.res_it && ( res_it==res_end || other.atm_it==atm_it );
00272 }
00273 typename do_add_const_to_ref<Atom,is_const>::type dereference() const {return *atm_it;}
00274 };
00275
00276
00277
00278
00279
00280 template <class Model,bool is_const>
00281 class Atoms_iterator_from_model:
00282 public boost::iterator_facade<
00283 Atoms_iterator_from_model<Model,is_const>,
00284 typename do_add_const<typename Model::Chain::Residue::Atom,is_const>::type,
00285 boost::forward_traversal_tag>
00286 {
00287 private:
00288 typedef typename Model::Chain::Residue::Atom Atom;
00289
00290 Chains_iterator_from_model<Model,is_const> chain_it;
00291 Chains_iterator_from_model<Model,is_const> chain_end;
00292 Atoms_iterator_from_chain<typename Model::Chain,is_const> atm_it;
00293 Atoms_iterator_from_chain<typename Model::Chain,is_const> atm_end;
00294 public:
00295 Atoms_iterator_from_model(typename do_add_const_to_ref<Model,is_const>::type model,bool is_end=false):
00296 chain_it(is_end?model.chains_end():model.chains_begin()),chain_end(model.chains_end())
00297 {
00298 if (chain_it!=chain_end){
00299 atm_it=chain_it->atoms_begin();
00300 atm_end=chain_it->atoms_end();
00301 make_valid();
00302 }
00303 }
00304
00305 bool is_end(){
00306 return chain_it==chain_end;
00307 }
00308
00309 private:
00310 friend class boost::iterator_core_access;
00311
00312 void increment(){
00313 ++atm_it;
00314 make_valid();
00315 }
00316
00317 void make_valid(){
00318 while (atm_it==atm_end){
00319 ++chain_it;
00320 if (chain_it==chain_end) break;
00321 atm_it=chain_it->atoms_begin();
00322 atm_end=chain_it->atoms_end();
00323 }
00324 }
00325
00326 bool equal(Atoms_iterator_from_model const& other) const{
00327 return chain_it==other.chain_it && ( chain_it==chain_end || other.atm_it==atm_it );
00328 }
00329 typename do_add_const_to_ref<Atom,is_const>::type dereference() const {return *atm_it;}
00330 };
00331
00332
00333
00334 template <class System,bool is_const>
00335 class Model_iterator_from_system:
00336 public boost::iterator_facade<
00337 Model_iterator_from_system<System,is_const>,
00338 typename do_add_const<typename System::Model,is_const>::type,
00339 boost::forward_traversal_tag>
00340 {
00341 private:
00342 typedef typename System::Model Model;
00343 public:
00344 Model_iterator_from_system(typename do_get_const_iterator<typename System::Model_container,is_const>::type it):
00345 model_it(it){}
00346
00347 private:
00348 friend class boost::iterator_core_access;
00349
00350 void increment(){++model_it;}
00351 bool equal(Model_iterator_from_system const& other) const{ return other.model_it==model_it; }
00352 typename do_add_const_to_ref<Model,is_const>::type dereference() const {return System::dereference(model_it);}
00353
00354
00355 typename do_get_const_iterator<typename System::Model_container,is_const>::type model_it;
00356 };
00357
00358
00359
00360
00361 template <class Model,bool is_const>
00362 class Coarse_atom_from_model:
00363 public boost::iterator_facade<
00364 Coarse_atom_from_model<Model,is_const>,
00365 typename do_add_const<typename Model::Chain::Residue::Coarse_atom,is_const>::type,
00366 boost::forward_traversal_tag>
00367 {
00368 private:
00369 typedef typename Model::Chain::Residue::Coarse_atom Coarse_atom;
00370 public:
00371 Coarse_atom_from_model(typename do_add_const_to_ref<Model,is_const>::type model,bool is_end=false):
00372 res_it(is_end?model.residues_end():model.residues_begin()),res_end(model.residues_end())
00373 {
00374 if (res_it!=res_end){
00375 atm_it=res_it->coarse_atoms_begin();
00376 atm_end=res_it->coarse_atoms_end();
00377 make_valid();
00378 }
00379 }
00380
00381 private:
00382 friend class boost::iterator_core_access;
00383
00384 void increment(){
00385 ++atm_it;
00386 make_valid();
00387 }
00388
00389 void make_valid(){
00390 while(atm_it==atm_end){
00391 ++res_it;
00392 if (res_it==res_end) break;
00393 atm_it=res_it->coarse_atoms_begin();
00394 atm_end=res_it->coarse_atoms_end();
00395 }
00396 }
00397 bool equal(Coarse_atom_from_model const& other) const{ return other.res_it==res_it && (res_it==res_end || other.atm_it==atm_it); }
00398 typename do_add_const_to_ref<Coarse_atom,is_const>::type dereference() const {return Model::Chain::Residue::dereference(atm_it);}
00399
00400
00401 Residues_iterator_from_model<Model,is_const> res_it;
00402 Residues_iterator_from_model<Model,is_const> res_end;
00403 typename do_get_const_iterator <typename Model::Chain::Residue::Coarse_atom_container,is_const>::type atm_it;
00404 typename do_get_const_iterator <typename Model::Chain::Residue::Coarse_atom_container,is_const>::type atm_end;
00405 };
00406
00407
00408 }
00410 }
00411
00412 #endif //ESBTL_ITERATORS_H