1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2    Copyright (c) 2011-2021 The plumed team
3    (see the PEOPLE file at the root of the distribution for a list of names)
4 
5    See http://www.plumed.org for more information.
6 
7    This file is part of plumed, version 2.
8 
9    plumed is free software: you can redistribute it and/or modify
10    it under the terms of the GNU Lesser General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13 
14    plumed is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public License
20    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #ifndef __PLUMED_tools_AtomNumber_h
23 #define __PLUMED_tools_AtomNumber_h
24 
25 #include "Exception.h"
26 #include <limits>
27 
28 namespace PLMD {
29 
30 /**
31 \ingroup TOOLBOX
32  Simple class to store the index of an atom.
33  It is just an unsigned, with all the methods inlined for better efficiency.
34  Its special thing is that it is only accessed through serial(), index(),
35  setSerial() and setIndex() methods, so that there
36  no ambiguity about using the "from 0" (index) or
37  "from 1" (serial) numbering (names as in VMD convention).
38 */
39 class AtomNumber {
40   unsigned index_;
41 /// Construct with a given index.
42 /// This constructor is kept private to avoid implicit cast.
43   explicit AtomNumber(unsigned);
44 public:
45 /// Initialize to index=0 (serial=1)
46   AtomNumber();
47 /// Returns the serial number
48   unsigned serial()const;
49 /// Returns the index number
50   unsigned index()const;
51 /// Sets the atom number by serial, returning a reference to the AtomNumber itself.
52   AtomNumber & setSerial(unsigned);
53 /// Sets the atom number by index, returning a reference to the AtomNumber itself.
54   AtomNumber & setIndex(unsigned);
55 /// Returns an AtomNumber with a specified serial.
56   static AtomNumber serial(unsigned);
57 /// Returns an AtomNumber with a specified index.
58   static AtomNumber index(unsigned);
59 /// Comparison operators
60   friend bool operator<(const AtomNumber&,const AtomNumber&);
61 /// Comparison operators
62   friend bool operator>(const AtomNumber&,const AtomNumber&);
63 /// Comparison operators
64   friend bool operator<=(const AtomNumber&,const AtomNumber&);
65 /// Comparison operators
66   friend bool operator>=(const AtomNumber&,const AtomNumber&);
67 /// Comparison operators
68   friend bool operator==(const AtomNumber&,const AtomNumber&);
69 /// Comparison operators
70   friend bool operator!=(const AtomNumber&,const AtomNumber&);
71 };
72 
73 inline
AtomNumber()74 AtomNumber::AtomNumber() {
75   index_=0;
76 }
77 
78 inline
AtomNumber(unsigned i)79 AtomNumber::AtomNumber(unsigned i) {
80   index_=i;
81 }
82 
83 inline
serial()84 unsigned AtomNumber::serial()const {
85   return index_+1;
86 }
87 
88 inline
index()89 unsigned AtomNumber::index()const {
90   return index_;
91 }
92 
93 inline
setSerial(unsigned i)94 AtomNumber & AtomNumber::setSerial(unsigned i) {
95   plumed_massert(i>0,"serial of an atom cannot be zero");
96   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
97   index_=i-1;
98   return *this;
99 }
100 
101 inline
setIndex(unsigned i)102 AtomNumber & AtomNumber::setIndex(unsigned i) {
103   index_=i;
104   return *this;
105 }
106 
107 inline
serial(unsigned i)108 AtomNumber AtomNumber::serial(unsigned i) {
109   plumed_massert(i>0,"serial of an atom cannot be zero");
110   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
111   return AtomNumber(i-1);
112 }
113 
114 inline
index(unsigned i)115 AtomNumber AtomNumber::index(unsigned i) {
116   return AtomNumber(i);
117 }
118 
119 inline
120 bool operator<(const AtomNumber&a,const AtomNumber&b) {
121   return a.index_<b.index_;
122 }
123 
124 inline
125 bool operator>(const AtomNumber&a,const AtomNumber&b) {
126   return a.index_>b.index_;
127 }
128 
129 inline
130 bool operator<=(const AtomNumber&a,const AtomNumber&b) {
131   return a.index_<=b.index_;
132 }
133 
134 inline
135 bool operator>=(const AtomNumber&a,const AtomNumber&b) {
136   return a.index_>=b.index_;
137 }
138 
139 inline
140 bool operator==(const AtomNumber&a,const AtomNumber&b) {
141   return a.index_==b.index_;
142 }
143 
144 inline
145 bool operator!=(const AtomNumber&a,const AtomNumber&b) {
146   return a.index_!=b.index_;
147 }
148 
149 }
150 
151 #endif
152 
153