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