First commit
[anna.git] / include / anna / core / util / Millisecond.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_core_util_Millisecond_hpp
38 #define anna_core_util_Millisecond_hpp
39
40 #include <time.h>
41
42 #include <string>
43
44 #include <anna/config/defines.hpp>
45 #include <anna/core/RuntimeException.hpp>
46
47 namespace anna {
48
49 class Second;
50 class Microsecond;
51
52 class Millisecond {
53 public:
54   typedef Integer64 type_t;
55
56   /**
57    * Constructor
58    */
59   Millisecond() : a_value(0) {;}
60
61   /**
62    * Constructor.
63    * \param value Valor inicial de esta instancia.
64    */
65   explicit Millisecond(const type_t value) : a_value(value) {;}
66
67   /**
68    * Constructor copia.
69    * \param other Instancia de la que copiar.
70    */
71   Millisecond(const Millisecond& other) : a_value(other.a_value) {;}
72
73   /**
74    * Constructor copia.
75    * \param other Instancia de la que copiar.
76    */
77   Millisecond(const Second& other);
78
79   /**
80    * Constructor copia.
81    * \param other Instancia de la que copiar.
82    */
83   Millisecond(const Microsecond& other);
84
85   /**
86    * Conversor a numérico.
87    * \return El valor asociado a esta instancia.
88    */
89   operator type_t () const throw() { return a_value; }
90
91   /**
92    * \internal
93    */
94   type_t& refValue() throw() { return a_value; }
95
96   Millisecond& operator= (const type_t other) throw() { a_value = other; return *this; }
97
98   Millisecond& operator= (const Millisecond& other) throw() { a_value = other.a_value; return *this; }
99
100   Millisecond& operator= (const Second& other) throw();
101
102   Millisecond& operator= (const Microsecond& other) throw();
103
104   bool operator== (const Millisecond& other) const throw() { return a_value == other.a_value; }
105
106   bool operator== (const Second& other) const throw();
107
108   bool operator== (const Microsecond& other) const throw();
109
110   bool operator!= (const Millisecond& other) const throw() { return a_value != other.a_value; }
111
112   bool operator!= (const Second& other) const throw();
113
114   bool operator!= (const Microsecond& other) const throw();
115
116   bool operator> (const Millisecond& other) const throw() { return a_value > other.a_value; }
117
118   bool operator> (const Second& other) const throw();
119
120   bool operator> (const Microsecond& other) const throw();
121
122   bool operator< (const Millisecond& other) const throw() { return a_value < other.a_value; }
123
124   bool operator< (const Second& other) const throw();
125
126   bool operator< (const Microsecond& other) const throw();
127
128   bool operator>= (const Millisecond& other) const throw() { return a_value >= other.a_value; }
129
130   bool operator>= (const Second& other) const throw() { return (operator==(other) == true) ? true : operator>(other); }
131
132   bool operator>= (const Microsecond& other) const throw() { return (operator==(other) == true) ? true : operator>(other); }
133
134   bool operator<= (const Millisecond& other) const throw() { return a_value <= other.a_value; }
135
136   bool operator<= (const Second& other) const throw() { return (operator==(other) == true) ? true : operator<(other); }
137
138   bool operator<= (const Microsecond& other) const throw() { return (operator==(other) == true) ? true : operator<(other); }
139
140   Millisecond& operator+= (const Millisecond& other) throw() { a_value += other.a_value; return *this; }
141
142   Millisecond& operator-= (const Millisecond& other) throw() {(a_value > other.a_value) ? (a_value -= other.a_value) : (a_value = 0); return *this; }
143
144   /**
145    * Devuelve el valor asociado a esta instancia.
146    * \return el valor asociado a esta instancia.
147    */
148   type_t getValue() const throw() { return a_value; }
149
150   /**
151    * Si el valor de esta instancia es positivo devuelve el valor asociado a esta instancia en una estructura de
152    * time \em timeval usada habitualmente para temporizar operaciones a nivel de SO, en otro caso retorna NULL.
153    * \param tv Instancia sobre la que guardar el valor en caso de que se éste tenga un valor positivo.
154    * \return Si el valor de esta instancia es positivo devuelve el valor asociado a esta instancia en una estructura de
155    * time \em timeval usada habitualmente para temporizar operaciones a nivel de SO, en otro caso retorna NULL.
156    */
157   timeval* getTimeVal(timeval& tv) const throw();
158
159   /**
160    * Devuelve la hora actual de sistema expresada en milisegundos transcurridos desde el 1 de Enero de 1970
161    * \return la hora actual de sistema expresada en milisegundos transcurridos desde el 1 de Enero de 1970
162    */
163   static Millisecond getTime() throw();
164
165   /**
166    * Devuelve una cadena con el valor de esta instancia y las unidades "ms".
167    * \return una cadena con el valor de esta instancia y las unidades "ms".
168    */
169   std::string asString() const throw();
170
171   /**
172    * Obtiene los microsegundos del valor contenido en la cadena recibida como parámetro.
173    * \param value Cadena que contiene los microsegundos habrá sido obtenida con #asString.
174    * \return los microsegundos del valor contenido en la cadena recibida como parámetro.
175    */
176   static Millisecond fromString(const std::string& value) throw(RuntimeException);
177
178 private:
179   type_t a_value;
180
181   friend class Second;
182   friend class Microsecond;
183
184   friend class Millisecond operator / (const Millisecond& left, const Millisecond& right) throw();
185   friend class Millisecond operator + (const Millisecond& left, const Millisecond& right) throw();
186   friend class Millisecond operator - (const Millisecond& left, const Millisecond& right) throw();
187   friend class Millisecond operator / (const Millisecond& left, const int right) throw();
188   friend class Millisecond operator / (const Millisecond& left, const unsigned int right) throw();
189   friend class Millisecond operator *(const Millisecond& left, const int right) throw();
190 };
191
192 inline Millisecond operator / (const Millisecond& left, const Millisecond& right)
193 throw() {
194   return Millisecond(left.a_value / right.a_value);
195 }
196
197 inline Millisecond operator + (const Millisecond& left, const Millisecond& right)
198 throw() {
199   return Millisecond(left.a_value + right.a_value);
200 }
201
202 inline Millisecond operator - (const Millisecond& left, const Millisecond& right)
203 throw() {
204   return Millisecond(left.a_value - right.a_value);
205 }
206
207 inline Millisecond operator / (const Millisecond& left, const int right)
208 throw() {
209   return Millisecond(left.a_value / right);
210 }
211
212 inline Millisecond operator / (const Millisecond& left, const unsigned int right)
213 throw() {
214   return Millisecond(left.a_value / right);
215 }
216
217 inline Millisecond operator *(const Millisecond& left, const int right)
218 throw() {
219   return Millisecond(left.a_value * right);
220 }
221
222 }
223
224 #endif