00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #ifndef BTK_BUILDABLE_ATOM_DECORATOR_H
00026 #define BTK_BUILDABLE_ATOM_DECORATOR_H
00027
00028 #include "atom.h"
00029 #include "buildable_atom_group_concept.h"
00030
00031 #include <boost/concept_check.hpp>
00032
00033 #include <map>
00034 #include <set>
00035
00036
00037 namespace BTK {
00038
00047 template <typename AtomBase>
00048 class BuildableAtomDecorator : public AtomBase {
00049 BOOST_CLASS_REQUIRE2(AtomBase,Atom,boost,ConvertibleConcept);
00050
00051 typedef AtomBase base_type;
00052 typedef BuildableAtomDecorator<AtomBase> self_type;
00053
00055 typedef std::set<self_type*> adjacent_container_t;
00056 typedef std::map<self_type*,unsigned> bond_cache_t;
00057 typedef BuildableAtomGroupConcept buildable_group_t;
00058
00059 public:
00060 typedef typename adjacent_container_t::iterator adjacent_iterator;
00061 typedef typename adjacent_container_t::const_iterator const_adjacent_iterator;
00062
00063
00064 BuildableAtomDecorator()
00065 : base_type(),
00066 _adjacent(),
00067 _is_built(false),
00068 _is_bond_distance_cached(false),
00069 _bond_distance_cache(),
00070 _buildable_group(0){}
00071
00075 BuildableAtomDecorator(const self_type& source)
00076 : base_type(source),
00077 _adjacent(),
00078 _is_built(source._is_built),
00079 _is_bond_distance_cached(false),
00080 _bond_distance_cache(),
00081 _buildable_group(0) {}
00082
00086 BuildableAtomDecorator(const base_type& a)
00087 : base_type(a),
00088 _adjacent(),
00089 _is_built(false),
00090 _is_bond_distance_cached(false),
00091 _bond_distance_cache(),
00092 _buildable_group(0) {}
00093
00094 ~BuildableAtomDecorator() {}
00095
00096
00100 self_type&
00101 operator=(const self_type& rhs)
00102 {
00103 if( &rhs == this ) return *this;
00104 base_type::operator=(rhs);
00105 _adjacent.clear();
00106 _is_built = rhs._is_built;
00107 _is_bond_distance_cached = false;
00108 _bond_distance_cache.clear();
00109 _buildable_group = 0;
00110 return *this;
00111 }
00112
00116 self_type&
00117 operator=(const base_type& rhs)
00118 {
00119 base_type::operator=(rhs);
00120 _adjacent.clear();
00121 _is_built = false;
00122 _is_bond_distance_cached = false;
00123 _bond_distance_cache.clear();
00124 _buildable_group = 0;
00125 return *this;
00126 }
00127
00129 bool is_built() const { return _is_built; }
00130 void set_is_built(bool i) { this->_is_built = i; }
00131
00139
00140
00144 bool is_bond_distance_cached() const { return _is_bond_distance_cached; }
00145
00148 void
00149 set_is_bond_distance_cached(bool i)
00150 {
00151 _is_bond_distance_cached = i;
00152 if(! _is_bond_distance_cached ) _bond_distance_cache.clear();
00153 }
00154
00161 unsigned
00162 bond_distance_4(self_type& a2)
00163 {
00164 typename bond_cache_t::const_iterator cib = _bond_distance_cache.find(&a2);
00165 if( cib == _bond_distance_cache.end() ) {
00166 return 5;
00167 }else{
00168 return cib->second;
00169 }
00170 }
00171
00174
00175 void
00176 set_bond_distance_4(self_type& a2,
00177 unsigned dist)
00178 {
00179 if (dist >= 5) return;
00180 _bond_distance_cache[&a2] = dist;
00181 }
00183
00184 adjacent_iterator adjacent_begin() { return _adjacent.begin(); }
00185 adjacent_iterator adjacent_end() { return _adjacent.end(); }
00186
00189 template <typename AtomType>
00190 void
00191 add_adjacent(AtomType& next_atom)
00192 {
00193 if(this==&next_atom) return;
00194
00195 _adjacent.insert(static_cast<self_type*>(&next_atom));
00196 }
00197
00201 bool
00202 build()
00203 {
00204 if(_is_built) return true;
00205 if(_buildable_group) return _buildable_group->build_atom(atom_index(),false);
00206 else return false;
00207 }
00208
00212 bool
00213 boot_build()
00214 {
00215 if(_is_built) return true;
00216 if(_buildable_group) return _buildable_group->build_atom(atom_index(),true);
00217 else return false;
00218 }
00219
00223 void set_buildable_group(buildable_group_t& g) { _buildable_group = &g; }
00224
00225 private:
00226 adjacent_container_t _adjacent;
00227 bool _is_built;
00228 bool _is_bond_distance_cached;
00229 bond_cache_t _bond_distance_cache;
00230 buildable_group_t* _buildable_group;
00231 };
00232
00233 }
00234
00235 #endif