]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/ratio/example/si_physics.cpp
1 // ratio_test.cpp ----------------------------------------------------------//
3 // Copyright 2008 Howard Hinnant
4 // Copyright 2008 Beman Dawes
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
10 #include <boost/ratio/ratio.hpp>
11 #include "duration.hpp"
15 // Example type-safe "physics" code interoperating with chrono::duration types
16 // and taking advantage of the std::ratio infrastructure and design philosophy.
18 // length - mimics chrono::duration except restricts representation to double.
19 // Uses boost::ratio facilities for length units conversions.
21 template <class Ratio
>
31 length(const double& len
) : len_(len
) {}
35 length(const length
<R
>& d
)
36 : len_(d
.count() * boost::ratio_divide
<Ratio
, R
>::type::den
/
37 boost::ratio_divide
<Ratio
, R
>::type::num
) {}
41 double count() const {return len_
;}
45 length
& operator+=(const length
& d
) {len_
+= d
.count(); return *this;}
46 length
& operator-=(const length
& d
) {len_
-= d
.count(); return *this;}
48 length
operator+() const {return *this;}
49 length
operator-() const {return length(-len_
);}
51 length
& operator*=(double rhs
) {len_
*= rhs
; return *this;}
52 length
& operator/=(double rhs
) {len_
/= rhs
; return *this;}
55 // Sparse sampling of length units
56 typedef length
<boost::ratio
<1> > meter
; // set meter as "unity"
57 typedef length
<boost::centi
> centimeter
; // 1/100 meter
58 typedef length
<boost::kilo
> kilometer
; // 1000 meters
59 typedef length
<boost::ratio
<254, 10000> > inch
; // 254/10000 meters
60 // length takes ratio instead of two integral types so that definitions can be made like so:
61 typedef length
<boost::ratio_multiply
<boost::ratio
<12>, inch::ratio
>::type
> foot
; // 12 inchs
62 typedef length
<boost::ratio_multiply
<boost::ratio
<5280>, foot::ratio
>::type
> mile
; // 5280 feet
64 // Need a floating point definition of seconds
65 typedef boost_ex::chrono::duration
<double> seconds
; // unity
66 // Demo of (scientific) support for sub-nanosecond resolutions
67 typedef boost_ex::chrono::duration
<double, boost::pico
> picosecond
; // 10^-12 seconds
68 typedef boost_ex::chrono::duration
<double, boost::femto
> femtosecond
; // 10^-15 seconds
69 typedef boost_ex::chrono::duration
<double, boost::atto
> attosecond
; // 10^-18 seconds
71 // A very brief proof-of-concept for SIUnits-like library
72 // Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())
73 template <class R1
, class R2
>
79 typedef R2 distance_dim
;
82 double get() const {return q_
;}
83 void set(double q
) {q_
= q
;}
87 class quantity
<boost::ratio
<1>, boost::ratio
<0> >
92 quantity(seconds d
) : q_(d
.count()) {} // note: only User1::seconds needed here
94 double get() const {return q_
;}
95 void set(double q
) {q_
= q
;}
99 class quantity
<boost::ratio
<0>, boost::ratio
<1> >
103 quantity() : q_(1) {}
104 quantity(meter d
) : q_(d
.count()) {} // note: only User1::meter needed here
106 double get() const {return q_
;}
107 void set(double q
) {q_
= q
;}
111 class quantity
<boost::ratio
<0>, boost::ratio
<0> >
115 quantity() : q_(1) {}
116 quantity(double d
) : q_(d
) {}
118 double get() const {return q_
;}
119 void set(double q
) {q_
= q
;}
123 typedef quantity
<boost::ratio
<0>, boost::ratio
<0> > Scalar
;
124 typedef quantity
<boost::ratio
<1>, boost::ratio
<0> > Time
; // second
125 typedef quantity
<boost::ratio
<0>, boost::ratio
<1> > Distance
; // meter
126 typedef quantity
<boost::ratio
<-1>, boost::ratio
<1> > Speed
; // meter/second
127 typedef quantity
<boost::ratio
<-2>, boost::ratio
<1> > Acceleration
; // meter/second^2
129 template <class R1
, class R2
, class R3
, class R4
>
130 quantity
<typename
boost::ratio_subtract
<R1
, R3
>::type
, typename
boost::ratio_subtract
<R2
, R4
>::type
>
131 operator/(const quantity
<R1
, R2
>& x
, const quantity
<R3
, R4
>& y
)
133 typedef quantity
<typename
boost::ratio_subtract
<R1
, R3
>::type
, typename
boost::ratio_subtract
<R2
, R4
>::type
> R
;
135 r
.set(x
.get() / y
.get());
139 template <class R1
, class R2
, class R3
, class R4
>
140 quantity
<typename
boost::ratio_add
<R1
, R3
>::type
, typename
boost::ratio_add
<R2
, R4
>::type
>
141 operator*(const quantity
<R1
, R2
>& x
, const quantity
<R3
, R4
>& y
)
143 typedef quantity
<typename
boost::ratio_add
<R1
, R3
>::type
, typename
boost::ratio_add
<R2
, R4
>::type
> R
;
145 r
.set(x
.get() * y
.get());
149 template <class R1
, class R2
>
151 operator+(const quantity
<R1
, R2
>& x
, const quantity
<R1
, R2
>& y
)
153 typedef quantity
<R1
, R2
> R
;
155 r
.set(x
.get() + y
.get());
159 template <class R1
, class R2
>
161 operator-(const quantity
<R1
, R2
>& x
, const quantity
<R1
, R2
>& y
)
163 typedef quantity
<R1
, R2
> R
;
165 r
.set(x
.get() - y
.get());
169 // Example type-safe physics function
171 compute_distance(Speed v0
, Time t
, Acceleration a
)
173 return v0
* t
+ Scalar(.5) * a
* t
* t
; // if a units mistake is made here it won't compile
178 // Exercise example type-safe physics function and show interoperation
179 // of custom time durations (User1::seconds) and standard time durations (std::hours).
180 // Though input can be arbitrary (but type-safe) units, output is always in SI-units
181 // (a limitation of the simplified Units lib demoed here).
187 //~ typedef boost::ratio<8, BOOST_INTMAX_C(0x7FFFFFFFD)> R1;
188 //~ typedef boost::ratio<3, BOOST_INTMAX_C(0x7FFFFFFFD)> R2;
189 typedef User1::quantity
<boost::ratio_subtract
<boost::ratio
<0>, boost::ratio
<1> >::type
,
190 boost::ratio_subtract
<boost::ratio
<1>, boost::ratio
<0> >::type
> RR
;
191 //~ typedef boost::ratio_subtract<R1, R2>::type RS;
192 //~ std::cout << RS::num << '/' << RS::den << '\n';
195 std::cout
<< "*************\n";
196 std::cout
<< "* testUser1 *\n";
197 std::cout
<< "*************\n";
198 User1::Distance
d(( User1::mile(110) ));
199 boost_ex::chrono::hours
h((2));
200 User1::Time
t(( h
));
201 //~ boost_ex::chrono::seconds sss=boost_ex::chrono::duration_cast<boost_ex::chrono::seconds>(h);
202 //~ User1::seconds sss((120));
203 //~ User1::Time t(( sss ));
205 //typedef User1::quantity<boost::ratio_subtract<User1::Distance::time_dim, User1::Time::time_dim >::type,
206 // boost::ratio_subtract<User1::Distance::distance_dim, User1::Time::distance_dim >::type > R;
208 //r.set(d.get() / t.get());
212 User1::Speed s
= d
/ t
;
213 std::cout
<< "Speed = " << s
.get() << " meters/sec\n";
214 User1::Acceleration a
= User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
215 std::cout
<< "Acceleration = " << a
.get() << " meters/sec^2\n";
216 User1::Distance df
= compute_distance(s
, User1::Time( User1::seconds(0.5) ), a
);
217 std::cout
<< "Distance = " << df
.get() << " meters\n";
218 std::cout
<< "There are " << User1::mile::ratio::den
<< '/' << User1::mile::ratio::num
<< " miles/meter";
221 std::cout
<< " which is approximately " << mi
.count() << '\n';
222 std::cout
<< "There are " << User1::mile::ratio::num
<< '/' << User1::mile::ratio::den
<< " meters/mile";
225 std::cout
<< " which is approximately " << mt
.count() << '\n';
226 User1::attosecond
as(1);
227 User1::seconds sec
= as
;
228 std::cout
<< "1 attosecond is " << sec
.count() << " seconds\n";
229 std::cout
<< "sec = as; // compiles\n";
230 sec
= User1::seconds(1);
232 std::cout
<< "1 second is " << as
.count() << " attoseconds\n";
233 std::cout
<< "as = sec; // compiles\n";