1 /******************************************************************************
2
3 This source file is part of the Avogadro project.
4
5 Copyright 2011-2012 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #ifndef AVOGADRO_CORE_BOND_H
18 #define AVOGADRO_CORE_BOND_H
19
20 #include "avogadrocore.h"
21
22 #include "atom.h"
23
24 namespace Avogadro {
25 namespace Core {
26
27 /**
28 * @class Bond bond.h <avogadro/core/bond.h>
29 * The Bond class represents a bond in a molecule.
30 * To use the appropriate bond implementation for a specific molecule
31 * implementation, use the [MoleculeClass]::BondType typedef.
32 */
33 template <class Molecule_T>
34 class BondTemplate
35 {
36 public:
37 typedef Molecule_T MoleculeType;
38 typedef typename Molecule_T::AtomType AtomType;
39
40 /** Creates a new, invalid bond object. */
41 BondTemplate();
42
43 /**
44 * Creates a bond object representing a bond at index @p i in molecule @p m.
45 */
46 BondTemplate(MoleculeType* m, Index i);
47
48 /**
49 * @return True if @a this and @a other share the same index and molecule.
50 */
51 bool operator==(const BondTemplate<MoleculeType>& other) const;
52
53 /**
54 * @return True if @a this and @a other do not share the same index or
55 * molecule.
56 */
57 bool operator!=(const BondTemplate<MoleculeType>& other) const;
58
59 /**
60 * Prefix increment operator. Increment this Bond's index by 1 and return a
61 * self-reference. Check isValid() before calling any other methods.
62 */
63 BondTemplate<MoleculeType>& operator++();
64
65 /**
66 * Postfix increment operator. Increment this Bond's index by 1 and return a
67 * copy of the current Atom. Check isValid() before calling any other methods.
68 */
69 BondTemplate<MoleculeType> operator++(int);
70
71 /**
72 * Prefix decrement operator. Decrement this Bond's index by 1 and return a
73 * self-reference. Check isValid() before calling any other methods.
74 */
75 BondTemplate<MoleculeType>& operator--();
76
77 /**
78 * Postfix decrement operator. Decrement this Bond's index by 1 and return a
79 * copy of the current Atom. Check isValid() before calling any other methods.
80 */
81 BondTemplate<MoleculeType> operator--(int);
82
83 /**
84 * @return True if the molecule is set and the index is less than the number
85 * of bonds.
86 */
87 bool isValid() const;
88
89 /**
90 * @return The molecule that contains this Bond.
91 */
92 MoleculeType* molecule() const;
93
94 /**
95 * @return The index of this bond in molecule().
96 */
97 Index index() const;
98
99 /**
100 * An atom in the bond, such that atom1().index() < atom2.index().
101 * @{
102 */
103 AtomType atom1() const;
104 AtomType atom2() const;
105 /** @} */
106
107 /**
108 * The bond's order (single = 1, double = 2, etc.)
109 * @{
110 */
111 void setOrder(unsigned char o);
112 unsigned char order() const;
113 /** @} */
114
115 private:
116 MoleculeType* m_molecule;
117 Index m_index;
118 };
119
120 template <class Molecule_T>
BondTemplate()121 BondTemplate<Molecule_T>::BondTemplate()
122 : m_molecule(nullptr), m_index(MaxIndex)
123 {
124 }
125
126 template <class Molecule_T>
BondTemplate(MoleculeType * m,Index i)127 BondTemplate<Molecule_T>::BondTemplate(MoleculeType* m, Index i)
128 : m_molecule(m), m_index(i)
129 {
130 }
131
132 template <class Molecule_T>
133 bool BondTemplate<Molecule_T>::operator==(
134 const BondTemplate<MoleculeType>& other) const
135 {
136 return m_molecule == other.m_molecule && m_index == other.m_index;
137 }
138
139 template <class Molecule_T>
140 bool BondTemplate<Molecule_T>::operator!=(
141 const BondTemplate<MoleculeType>& other) const
142 {
143 return m_molecule != other.m_molecule || m_index != other.m_index;
144 }
145
146 template <class Molecule_T>
147 BondTemplate<Molecule_T>& BondTemplate<Molecule_T>::operator++()
148 {
149 ++m_index;
150 return *this;
151 }
152
153 template <class Molecule_T>
154 BondTemplate<Molecule_T> BondTemplate<Molecule_T>::operator++(int)
155 {
156 BondTemplate<MoleculeType> result(m_molecule, m_index++);
157 return result;
158 }
159
160 template <class Molecule_T>
161 BondTemplate<Molecule_T>& BondTemplate<Molecule_T>::operator--()
162 {
163 --m_index;
164 return *this;
165 }
166
167 template <class Molecule_T>
168 BondTemplate<Molecule_T> BondTemplate<Molecule_T>::operator--(int)
169 {
170 BondTemplate<MoleculeType> result(m_molecule, m_index--);
171 return result;
172 }
173
174 template <class Molecule_T>
isValid()175 bool BondTemplate<Molecule_T>::isValid() const
176 {
177 return m_molecule && m_index < m_molecule->bondCount();
178 }
179
180 template <class Molecule_T>
181 typename BondTemplate<Molecule_T>::MoleculeType*
molecule()182 BondTemplate<Molecule_T>::molecule() const
183 {
184 return m_molecule;
185 }
186
187 template <class Molecule_T>
index()188 Index BondTemplate<Molecule_T>::index() const
189 {
190 return m_index;
191 }
192
193 template <class Molecule_T>
atom1()194 typename BondTemplate<Molecule_T>::AtomType BondTemplate<Molecule_T>::atom1()
195 const
196 {
197 return AtomType(m_molecule, m_molecule->bondPairs()[m_index].first);
198 }
199
200 template <class Molecule_T>
atom2()201 typename BondTemplate<Molecule_T>::AtomType BondTemplate<Molecule_T>::atom2()
202 const
203 {
204 return AtomType(m_molecule, m_molecule->bondPairs()[m_index].second);
205 }
206
207 template <class Molecule_T>
setOrder(unsigned char o)208 void BondTemplate<Molecule_T>::setOrder(unsigned char o)
209 {
210 m_molecule->setBondOrder(m_index, o);
211 }
212
213 template <class Molecule_T>
order()214 unsigned char BondTemplate<Molecule_T>::order() const
215 {
216 return m_molecule->bondOrders()[m_index];
217 }
218
219 } // end Core namespace
220 } // end Avogadro namespace
221
222 #endif // AVOGADRO_CORE_BOND_H
223