astrotypes  0.0
BoostDurationCast.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 #ifndef PSS_ASTROTYPES_UNITS_BOOSTDURATIONCAST_H
25 #define PSS_ASTROTYPES_UNITS_BOOSTDURATIONCAST_H
26 
27 #include "TimeUnits.h"
28 #include <chrono>
29 
30 namespace pss {
31 namespace astrotypes {
32 namespace units {
33 
41 template<class BoostUnit>
43 
49 template<typename BoostType, typename ChronoType>
51 
57 template<typename BoostType, typename ChronoType>
59 
76 template<typename BoostType, typename ChronoType>
78 
90 template<typename BoostQuantity, typename ChronoNumericalRep, typename PeriodType>
91 constexpr
92 typename std::enable_if<boost::units::is_quantity<BoostQuantity>::value
93  && boost::units::is_unit_of_dimension<typename BoostQuantity::unit_type, boost::units::time_dimension>::value
95  , BoostQuantity // this is the type to convert to
96  >::type
97 duration_cast(const std::chrono::duration<ChronoNumericalRep, PeriodType>& duration)
98 {
99  typedef std::chrono::duration<typename BoostQuantity::value_type
101  return BoostQuantity().from_value(std::chrono::duration_cast<chrono_duration>(duration).count());
102 }
103 
104 // specialisation - when they are of equivalent types we can just reinterpet cast and save a copy
105 // non const version
106 template<typename BoostQuantity, typename ChronoNumericalRep, typename PeriodType>
107 constexpr
108 typename std::enable_if<boost::units::is_quantity<BoostQuantity>::value
109  && boost::units::is_unit_of_dimension<typename BoostQuantity::unit_type, boost::units::time_dimension>::value
110  && is_equivalent<BoostQuantity, std::chrono::duration<ChronoNumericalRep, PeriodType>>::value
111  , BoostQuantity& // this is the type to convert to
112  >::type
113 duration_cast(std::chrono::duration<ChronoNumericalRep, PeriodType>& duration)
114 {
115  return reinterpret_cast<BoostQuantity&>(duration);
116 }
117 
118 // const version
119 template<typename BoostQuantity, typename ChronoNumericalRep, typename PeriodType>
120 constexpr
121 typename std::enable_if<boost::units::is_quantity<BoostQuantity>::value
122  && boost::units::is_unit_of_dimension<typename BoostQuantity::unit_type, boost::units::time_dimension>::value
123  && is_equivalent<BoostQuantity, std::chrono::duration<ChronoNumericalRep, PeriodType>>::value
124  , const BoostQuantity& // this is the type to convert to
125  >::type
126 duration_cast(const std::chrono::duration<ChronoNumericalRep, PeriodType>& duration)
127 {
128  return reinterpret_cast<const BoostQuantity&>(duration);
129 }
130 
131 // --------- boost::units::quantity -> std::chron::duration conversions
132 template<typename ChronoDuration, typename BoostNumericalRep, typename BoostUnit>
133 constexpr
134 typename std::enable_if<!boost::units::is_quantity<ChronoDuration>::value
135  && boost::units::is_unit_of_dimension<BoostUnit, boost::units::time_dimension>::value
136  && !is_equivalent<boost::units::quantity<BoostUnit, BoostNumericalRep>, ChronoDuration>::value
137  , ChronoDuration // this is the type to convert to
138  >::type
139 duration_cast(const boost::units::quantity<BoostUnit, BoostNumericalRep>& duration)
140 {
141  typedef std::chrono::duration<BoostNumericalRep
142  , typename boost_unit_to_std_ratio<BoostUnit>::type> equiv_chrono_duration;
143  return std::chrono::duration_cast<ChronoDuration>(reinterpret_cast<const equiv_chrono_duration &>(duration));
144 }
145 
146 template<typename ChronoDuration, typename BoostNumericalRep, typename BoostUnit>
147 constexpr
148 typename std::enable_if<!boost::units::is_quantity<ChronoDuration>::value
149  && boost::units::is_unit_of_dimension<BoostUnit, boost::units::time_dimension>::value
150  && is_equivalent<boost::units::quantity<BoostUnit, BoostNumericalRep>, ChronoDuration>::value
151  , ChronoDuration& // this is the type to convert to
152  >::type
153 duration_cast(boost::units::quantity<BoostUnit, BoostNumericalRep>& duration)
154 {
155  return reinterpret_cast<ChronoDuration&>(duration);
156 }
157 
158 template<typename ChronoDuration, typename BoostNumericalRep, typename BoostUnit>
159 constexpr
160 typename std::enable_if<boost::units::is_unit_of_dimension<BoostUnit, boost::units::time_dimension>::value
161  && is_equivalent<boost::units::quantity<BoostUnit, BoostNumericalRep>, ChronoDuration>::value
162  , const ChronoDuration& // this is the type to convert to
163  >::type
164 duration_cast(const boost::units::quantity<BoostUnit, BoostNumericalRep>& duration)
165 {
166  return reinterpret_cast<const ChronoDuration&>(duration);
167 }
168 
169 template<typename BoostDuration, typename BoostNumericalRep, typename BoostUnit>
170 constexpr
171 typename std::enable_if<boost::units::is_quantity<BoostDuration>::value
172  && !is_equivalent<boost::units::quantity<BoostUnit, BoostNumericalRep>, BoostDuration>::value
173  , BoostDuration // this is the type to convert to
174  >::type
175 duration_cast(boost::units::quantity<BoostUnit, BoostNumericalRep> const& duration)
176 {
177  return static_cast<BoostDuration>(duration);
178 }
179 
180 } // namespace units
181 } // namespace astrotypes
182 } // namespace pss
184 
185 #endif // PSS_ASTROTYPES_UNITS_BOOSTDURATIONCAST_H
constexpr std::enable_if< boost::units::is_quantity< BoostDuration >::value &&!is_equivalent< boost::units::quantity< BoostUnit, BoostNumericalRep >, BoostDuration >::value, BoostDuration >::type duration_cast(boost::units::quantity< BoostUnit, BoostNumericalRep > const &duration)
conversion helper from boost time units to the std::chrono::duration::period equivalent ...
determine is the NumericalRep of the chrono::duration and the boost::quatity are equivalent ...
determine is the units of the chrono::duration and the boost::quatity are equivalent ...
determine is the boost::quanity and the std::chrono:;duration are equivalent reperesentations i...
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.