00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00023
00024 #ifndef BTK_MOLECULES_ATOMIC_STRUCTURE_HPP
00025 #define BTK_MOLECULES_ATOMIC_STRUCTURE_HPP
00026
00027 #include <vector>
00028 #include <ostream>
00029 #include <algorithm>
00030 #include <iterator>
00031
00032 #include <btk/core/utility/btk_sequence.hpp>
00033 #include <btk/core/utility/chemically_typed_object.hpp>
00034 #include <btk/core/concepts/atom_concept.hpp>
00035 #include <btk/core/concepts/atom_iterator_concept.hpp>
00036
00037 namespace BTK {
00038 namespace MOLECULES {
00039
00040
00052 template <typename AtomType,
00053 typename ChemicalTypeSystemType,
00054 typename DictionaryType,
00055 typename StorageStrategy = std::vector<AtomType> >
00056 class AtomicStructure :
00057 public BTK::UTILITY::ChemicallyTypedObject<ChemicalTypeSystemType,
00058 DictionaryType>,
00059 protected BTK::UTILITY::BTKSequence<AtomType,StorageStrategy>
00060 {
00061 typedef BTK::UTILITY::ChemicallyTypedObject<ChemicalTypeSystemType,
00062 DictionaryType> cto_type;
00063 typedef BTK::UTILITY::BTKSequence<AtomType,StorageStrategy> btk_seq_type;
00064 typedef AtomicStructure<AtomType,
00065 ChemicalTypeSystemType,
00066 DictionaryType,
00067 StorageStrategy> self_type;
00068 public:
00069 IMPORT_CHEMICALLY_TYPED_OBJECT_TYPES(cto_type);
00070 IMPORT_BTK_CONTAINER_TYPES(btk_seq_type);
00071
00072 typedef value_type atom_type;
00073 typedef iterator atom_iterator;
00074 typedef const_iterator const_atom_iterator;
00075 typedef reverse_iterator reverse_atom_iterator;
00076 typedef const_reverse_iterator const_reverse_atom_iterator;
00077 typedef id_type structure_id_type;
00078 typedef typename atom_type::id_type atom_id_type;
00079
00080 BOOST_CLASS_REQUIRE(atom_type,BTK::CONCEPTS,AtomConcept);
00081 BOOST_CLASS_REQUIRE(iterator,BTK::CONCEPTS,MutableAtomIteratorConcept);
00082 BOOST_CLASS_REQUIRE(reverse_iterator,BTK::CONCEPTS,MutableAtomIteratorConcept);
00083 BOOST_CLASS_REQUIRE(const_iterator,BTK::CONCEPTS,AtomIteratorConcept);
00084 BOOST_CLASS_REQUIRE(const_reverse_iterator,BTK::CONCEPTS,AtomIteratorConcept);
00085
00086 AtomicStructure(self_type const & source) :
00087 cto_type(source), btk_seq_type(source) {}
00088
00089 virtual ~AtomicStructure() {}
00090
00091 IMPORT_BTK_CONTAINER_METHODS(btk_seq_type)
00092
00093
00094 size_type num_atoms() const { return btk_seq_type::size(); }
00095
00097
00098 atom_iterator structure_begin() { return btk_seq_type::begin(); }
00099 const_atom_iterator structure_begin() const { return btk_seq_type::begin(); }
00101
00103
00104 reverse_atom_iterator structure_rbegin() { return btk_seq_type::rbegin(); }
00105 const_reverse_atom_iterator structure_rbegin() const
00106 { return btk_seq_type::rbegin(); }
00108
00110
00111 atom_iterator structure_end() { return btk_seq_type::end(); }
00112 const_atom_iterator structure_end() const { return btk_seq_type::end(); }
00114
00116
00117 reverse_atom_iterator structure_rend() { return btk_seq_type::rend(); }
00118 const_reverse_atom_iterator structure_rend() const { return btk_seq_type::rend(); }
00120
00121 using cto_type::type;
00122 using cto_type::name;
00123 using cto_type::get_chemical_type_system;
00124
00126 virtual void set_chemical_type_system(chemical_type_system const & cts)
00127 {
00128
00129 cto_type::set_chemical_type_system(cts);
00130
00131
00132 for (atom_iterator ai = structure_begin(); ai != structure_end(); ++ai)
00133 ai->set_chemical_type_system(cts);
00134 }
00135
00139 virtual std::ostream & print(std::ostream & os,
00140 size_type first_atom_num = 1,
00141 size_type group_num = 1,
00142 char chain_id = ' ') const
00143 {
00144 const_atom_iterator ai;
00145 size_type atom_num = first_atom_num;
00146 size_type group = group_num;
00147
00148 for (ai = structure_begin(); ai != structure_end(); ++ai)
00149 ai->print(os,atom_num++,
00150 group,chain_id,
00151 name());
00152
00153 return os;
00154 }
00155
00156 virtual dictionary const & get_dictionary() const = 0;
00157 virtual dictionary & get_dictionary() = 0;
00158
00159 protected:
00160
00162
00163 AtomicStructure(size_type n = 0,
00164 const_reference t = value_type(),
00165 id_type type = id_type()) :
00166 cto_type(t.get_chemical_type_system(),type), btk_seq_type(n,t) {}
00167
00168 template <typename AtomIterator>
00169 AtomicStructure(AtomIterator i, AtomIterator j,
00170 id_type type = id_type()) :
00171 cto_type(i->get_chemical_type_system(),type), btk_seq_type(i,j)
00172 {
00173 boost::function_requires<BTK::CONCEPTS::AtomIteratorConcept<AtomIterator> >();
00174
00175
00176
00177
00178
00179
00180 typedef typename std::iterator_traits<AtomIterator>::value_type a_t;
00181 boost::function_requires<boost::ConvertibleConcept<a_t,atom_type> >();
00182 }
00184
00185 using cto_type::set_type;
00186
00189 self_type const & operator=(self_type const & rhs)
00190 {
00191 if (this == &rhs) return *this;
00192 cto_type::operator=(rhs);
00193 btk_seq_type::operator=(rhs);
00194 return *this;
00195 }
00196
00199 void swap(self_type & b)
00200 {
00201 cto_type::swap(b);
00202 btk_seq_type::swap(b);
00203 }
00204
00208
00209 bool operator==(self_type const & rhs) const {
00210 return (cto_type::operator==(rhs) && btk_seq_type::operator==(rhs));
00211 }
00212
00213 bool operator!=(self_type const & rhs) const {
00214 return !(operator==(rhs));
00215 }
00217
00222 bool operator<(self_type const & rhs) const {
00223 if (cto_type::operator<(rhs))
00224 return true;
00225 else if (cto_type::operator==(rhs))
00226 return btk_seq_type::operator<(rhs);
00227 else
00228 return false;
00229 }
00230 };
00231
00232 #define IMPORT_ATOMIC_STRUCTURE_TYPES(ASType) \
00233 IMPORT_CHEMICALLY_TYPED_OBJECT_TYPES(ASType) \
00234 IMPORT_BTK_CONTAINER_TYPES(ASType) \
00235 \
00236 typedef typename ASType::atom_type atom_type; \
00237 typedef typename ASType::atom_iterator atom_iterator; \
00238 typedef typename ASType::const_atom_iterator const_atom_iterator; \
00239 typedef typename ASType::reverse_atom_iterator reverse_atom_iterator; \
00240 typedef typename ASType::const_reverse_atom_iterator \
00241 const_reverse_atom_iterator; \
00242 typedef typename ASType::structure_id_type structure_id_type; \
00243 typedef typename ASType::atom_id_type atom_id_type;
00244
00245 template <typename AT, typename CTO, typename DICT, typename SS>
00246 std::ostream & operator<<(std::ostream & os, AtomicStructure<AT,CTO,DICT,SS> const & a)
00247 {
00248 return a.print(os);
00249 }
00250
00251 }
00252 }
00253
00254 #endif