astrotypes  0.0
Time.h
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2018 PulsarSearchSoft
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include "TimeUnits.h"
26 #include "BoostDurationCast.h"
27 #include "Quantity.h"
28 #include "JulianClock.h"
29 #include "J2000Clock.h"
30 #include "ModifiedJulianClock.h"
31 #include "cmath.h"
32 #include <chrono>
33 
34 #ifndef ASTROTYPES_UNITS_TIME_H
35 #define ASTROTYPES_UNITS_TIME_H
36 
37 namespace pss {
38 namespace astrotypes {
39 namespace units {
40 
41 // Dimension
42 typedef boost::units::time_dimension Time;
43 
44 // time points
45 typedef JulianClock::time_point JulianDate;
46 typedef ModifiedJulianClock::time_point ModifiedJulianDate;
47 typedef ModifiedJulianClock::time_point MJD;
48 typedef J2000Clock::time_point J2000;
49 
55 template<typename TimeUnit, typename NumericalRep>
56 class Quantity<TimeUnit
57  , NumericalRep
58  , typename std::enable_if<boost::units::is_unit_of_dimension<TimeUnit, boost::units::time_dimension>::value>::type>
59  : public boost::units::quantity<TimeUnit, NumericalRep>
60 {
61  typedef boost::units::quantity<TimeUnit, NumericalRep> BaseT;
62  typedef std::chrono::duration<NumericalRep, typename boost_unit_to_std_ratio<TimeUnit>::type> chrono_duration;
63 
64  public:
65  // reproduce the chrono typedefs
66  typedef NumericalRep rep;
67  typedef typename chrono_duration::period period;
68 
69  public:
73  Quantity() {}
74  Quantity(BaseT const& b) : BaseT(b) {}
75 
76  explicit Quantity(chrono_duration const& d) : BaseT(d.count()) {}
77 
82  template<typename UnitType, typename OtherDataType>
83  explicit Quantity(boost::units::quantity<UnitType, OtherDataType> const & quantity) : BaseT(quantity) {}
84 
88  operator chrono_duration const& () const { duration_cast<chrono_duration>(*this); };
89  operator chrono_duration& () { duration_cast<chrono_duration>(*this); };
90 
95  template<typename DurationType, typename PeriodType>
96  explicit Quantity(std::chrono::duration<DurationType, PeriodType> const & duration)
97  : BaseT(std::chrono::duration_cast<std::chrono::duration<DurationType, std::ratio<1, 1>>>(duration).count()
98  * seconds) {}
99 
103  template<typename UnitType, typename OtherDataType>
104  Quantity& operator=(boost::units::quantity<UnitType, OtherDataType> const& o)
105  {
106  static_cast<BaseT&>(*this) = BaseT(o);
107  return *this;
108  }
109 
110 };
111 
112 } // namespace units
113 } // namespace astrotypes
114 } // namespace pss
115 
116 namespace std {
117 namespace chrono {
118 
119 // interchangability between boost units and chrono types for > and < operators
120 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
121 inline bool operator<(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
122 {
123  return c < pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
124 }
125 
126 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
127 inline bool operator>(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
128 {
129  return c > pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
130 }
131 
132 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
133 inline bool operator<=(std::chrono::duration<Rep, Ratio> const& lhs, boost::units::quantity<Unit, Rep2> const& rhs){ return !(lhs > rhs); }
134 
135 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
136 inline bool operator>=(std::chrono::duration<Rep, Ratio> const& lhs, boost::units::quantity<Unit, Rep2> const& rhs){ return !(lhs < rhs); }
137 
138 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
139 inline bool operator==(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
140 {
141  return c == pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
142 }
143 
144 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
145 inline bool operator!=(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
146 {
147  return c != pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
148 }
149 
150 } // namespace chrono
151 } // namespace std
152 
153 // --------------------- std::crono::duration and boost::units::quantity interoperability ------------
154 namespace boost {
155 namespace units {
156 
157 // simple mathc operators with chrono types
158 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
159 boost::units::quantity<Unit, Rep2> operator+(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
160 {
161  return b + pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
162 }
163 
164 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
165 boost::units::quantity<Unit, Rep2> operator-(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
166 {
167  return b - pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
168 }
169 
170 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
171 boost::units::quantity<Unit, Rep2>& operator+=(boost::units::quantity<Unit, Rep2>& b, std::chrono::duration<Rep, Ratio> const& c)
172 {
173  return b += pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
174 }
175 
176 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
177 boost::units::quantity<Unit, Rep2>& operator-=(boost::units::quantity<Unit, Rep2>& b, std::chrono::duration<Rep, Ratio> const& c)
178 {
179  return b -= pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
180 }
181 
182 // deived by a duration
183 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
184 auto operator/(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
185  -> decltype(boost::units::quantity<Unit, Rep2>()/boost::units::quantity<Unit, Rep>())
186 {
187  return b / pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep>>(c);
188 }
189 
190 // interchangability between boost units and chrono types for > and < operators
191 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
192 bool operator<(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
193 {
194  return b < pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
195 }
196 
197 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
198 bool operator>(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
199 {
200  return b > pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
201 }
202 
203 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
204 inline bool operator<=(boost::units::quantity<Unit, Rep2> const& lhs, std::chrono::duration<Rep, Ratio> const& rhs){ return !(lhs > rhs); }
205 
206 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
207 inline bool operator>=(boost::units::quantity<Unit, Rep2> const& lhs, std::chrono::duration<Rep, Ratio> const& rhs){ return !(lhs < rhs); }
208 
209 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
210 bool operator==(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
211 {
212  return b == pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
213 }
214 
215 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
216 bool operator!=(boost::units::quantity<Unit, Rep2> const& b, std::chrono::duration<Rep, Ratio> const& c)
217 {
218  return b != pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep2>>(c);
219 }
220 
221 } // namespace units
222 } // namespace boost
223 
224 // overloads of some cmath functions to handle boost quantities
225 namespace std {
226 
227 template<typename Unit, typename Rep, typename T2>
228 struct common_type<boost::units::quantity<Unit, Rep>, T2> : public std::common_type<Rep, T2>
229 {};
230 
231 template<typename Unit, typename Rep, typename T2>
232 struct common_type<T2, boost::units::quantity<Unit, Rep>> : public std::common_type<T2, Rep>
233 {};
234 
235 // cmath helpers
236 template<typename Ratio, typename Rep>
237 std::chrono::duration<Rep, Ratio> abs(std::chrono::duration<Rep, Ratio> const& v) {
238  return std::chrono::duration<Rep, Ratio>(std::abs(v.count()));
239 }
240 
241 namespace chrono {
242 
243 // operators for standard math and boost::units::quantity types
244 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
245 std::chrono::duration<Rep, Ratio> operator+(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
246 {
247  return c + pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
248 }
249 
250 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
251 std::chrono::duration<Rep, Ratio> operator-(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
252 {
253  return c - pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
254 }
255 
256 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
257 std::chrono::duration<Rep, Ratio>& operator+=(std::chrono::duration<Rep, Ratio>& c, boost::units::quantity<Unit, Rep2> const& b)
258 {
259  return c += pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
260 }
261 
262 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
263 std::chrono::duration<Rep, Ratio>& operator-=(std::chrono::duration<Rep, Ratio>& c, boost::units::quantity<Unit, Rep2> const& b)
264 {
265  return c -= pss::astrotypes::units::duration_cast<std::chrono::duration<Rep, Ratio>>(b);
266 }
267 
268 template<typename Ratio, typename Rep, typename Unit, typename Rep2>
269 auto operator/(std::chrono::duration<Rep, Ratio> const& c, boost::units::quantity<Unit, Rep2> const& b)
270  -> decltype(boost::units::quantity<Unit, Rep>()/boost::units::quantity<Unit, Rep2>())
271 {
272  return pss::astrotypes::units::duration_cast<boost::units::quantity<Unit, Rep>>(c) / b;
273 }
274 
275 } // namespace chrono
276 } // namespace std
277 
278 #endif // ASTROTYPES_UNITS_TIME_H
bool operator==(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:210
Definition: Quantity.h:93
bool operator>=(boost::units::quantity< Unit, Rep2 > const &lhs, std::chrono::duration< Rep, Ratio > const &rhs)
Definition: Time.h:207
JulianClock::time_point JulianDate
Definition: Time.h:45
std::chrono::duration< Rep, Ratio > operator+(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:245
boost::units::time_dimension Time
Definition: Time.h:42
std::chrono::duration< Rep, Ratio > & operator+=(std::chrono::duration< Rep, Ratio > &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:257
STL namespace.
bool operator>(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:127
bool operator!=(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:145
Quantity(boost::units::quantity< UnitType, OtherDataType > const &quantity)
Conversion from other boost::units::quantity types.
Definition: Time.h:83
ModifiedJulianClock::time_point MJD
Definition: Time.h:47
Quantity(std::chrono::duration< DurationType, PeriodType > const &duration)
Conversion from std::chrono::duration types.
Definition: Time.h:96
auto operator/(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c) -> decltype(boost::units::quantity< Unit, Rep2 >()/boost::units::quantity< Unit, Rep >())
Definition: Time.h:184
std::chrono::duration< Rep, Ratio > operator-(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:251
boost::units::quantity< Unit, Rep2 > & operator-=(boost::units::quantity< Unit, Rep2 > &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:177
bool operator>=(std::chrono::duration< Rep, Ratio > const &lhs, boost::units::quantity< Unit, Rep2 > const &rhs)
Definition: Time.h:136
bool operator>(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:198
boost::units::quantity< Unit, Rep2 > operator-(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:165
bool operator!=(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:216
auto operator/(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b) -> decltype(boost::units::quantity< Unit, Rep >()/boost::units::quantity< Unit, Rep2 >())
Definition: Time.h:269
constexpr std::enable_if< boost::units::is_quantity< BoostQuantity >::value &&boost::units::is_unit_of_dimension< typename BoostQuantity::unit_type, boost::units::time_dimension >::value &&!is_equivalent< BoostQuantity, std::chrono::duration< ChronoNumericalRep, PeriodType > >::value, BoostQuantity >::type duration_cast(const std::chrono::duration< ChronoNumericalRep, PeriodType > &duration)
Mimic the std::duration_cast to convert to/from boost::units::quantity tyeps.
J2000Clock::time_point J2000
Definition: Time.h:48
boost::units::quantity< Unit, Rep2 > operator+(boost::units::quantity< Unit, Rep2 > const &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:159
bool operator==(std::chrono::duration< Rep, Ratio > const &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:139
boost::units::quantity< Unit, Rep2 > & operator+=(boost::units::quantity< Unit, Rep2 > &b, std::chrono::duration< Rep, Ratio > const &c)
Definition: Time.h:171
ModifiedJulianClock::time_point ModifiedJulianDate
Definition: Time.h:46
std::chrono::duration< Rep, Ratio > & operator-=(std::chrono::duration< Rep, Ratio > &c, boost::units::quantity< Unit, Rep2 > const &b)
Definition: Time.h:263