fix doc example typo
[boost.git] / boost / units / cmath.hpp
blobb9aedbfd982304b86f297ddd06638ebd69638c3a
1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
2 // unit/quantity manipulation and conversion
3 //
4 // Copyright (C) 2003-2008 Matthias Christian Schabel
5 // Copyright (C) 2007-2008 Steven Watanabe
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_UNITS_CMATH_HPP
12 #define BOOST_UNITS_CMATH_HPP
14 #include <boost/config/no_tr1/cmath.hpp>
15 #include <cstdlib>
17 #include <boost/math/special_functions/fpclassify.hpp>
18 #include <boost/math/special_functions/hypot.hpp>
19 #include <boost/math/special_functions/next.hpp>
20 #include <boost/math/special_functions/round.hpp>
21 #include <boost/math/special_functions/sign.hpp>
23 #include <boost/units/dimensionless_quantity.hpp>
24 #include <boost/units/pow.hpp>
25 #include <boost/units/quantity.hpp>
26 #include <boost/units/detail/cmath_impl.hpp>
28 #include <boost/units/systems/si/plane_angle.hpp>
30 /// \file
31 /// \brief Overloads of functions in \<cmath\> for quantities
32 ///
33 /// \detailed Only functions for which a dimensionally-correct result type
34 /// can be determined are overloaded. All functions work with dimensionless
35 /// quantities.
37 // BOOST_PREVENT_MACRO_SUBSTITUTION is needed on certain compilers that define
38 // some <cmath> functions as macros; it is used for all functions even though it
39 // isn't necessary -- I didn't want to think :)
41 // the form using namespace detail; return(f(x)); is used
42 // to enable ADL for UDTs
44 namespace boost {
46 namespace units {
48 template<class Unit,class Y>
49 inline
50 bool
51 isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
53 using boost::math::isfinite;
54 return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
57 template<class Unit,class Y>
58 inline
59 bool
60 isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
62 using boost::math::isinf;
63 return isinf BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
66 template<class Unit,class Y>
67 inline
68 bool
69 isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
71 using boost::math::isnan;
72 return isnan BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
75 template<class Unit,class Y>
76 inline
77 bool
78 isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
80 using boost::math::isnormal;
81 return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
84 template<class Unit,class Y>
85 inline
86 bool
87 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
88 const quantity<Unit,Y>& q2)
90 using namespace detail;
91 return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
94 template<class Unit,class Y>
95 inline
96 bool
97 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
98 const quantity<Unit,Y>& q2)
100 using namespace detail;
101 return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
104 template<class Unit,class Y>
105 inline
106 bool
107 isless BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
108 const quantity<Unit,Y>& q2)
110 using namespace detail;
111 return isless BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
114 template<class Unit,class Y>
115 inline
116 bool
117 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
118 const quantity<Unit,Y>& q2)
120 using namespace detail;
121 return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
124 template<class Unit,class Y>
125 inline
126 bool
127 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
128 const quantity<Unit,Y>& q2)
130 using namespace detail;
131 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
134 template<class Unit,class Y>
135 inline
136 bool
137 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
138 const quantity<Unit,Y>& q2)
140 using namespace detail;
141 return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
144 template<class Unit,class Y>
145 inline
146 quantity<Unit,Y>
147 abs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
149 using std::abs;
151 typedef quantity<Unit,Y> quantity_type;
153 return quantity_type::from_value(abs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
156 template<class Unit,class Y>
157 inline
158 quantity<Unit,Y>
159 ceil BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
161 using std::ceil;
163 typedef quantity<Unit,Y> quantity_type;
165 return quantity_type::from_value(ceil BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
168 template<class Unit,class Y>
169 inline
170 quantity<Unit,Y>
171 copysign BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
172 const quantity<Unit,Y>& q2)
174 using boost::math::copysign;
176 typedef quantity<Unit,Y> quantity_type;
178 return quantity_type::from_value(copysign BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
181 template<class Unit,class Y>
182 inline
183 quantity<Unit,Y>
184 fabs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
186 using std::fabs;
188 typedef quantity<Unit,Y> quantity_type;
190 return quantity_type::from_value(fabs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
193 template<class Unit,class Y>
194 inline
195 quantity<Unit,Y>
196 floor BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
198 using std::floor;
200 typedef quantity<Unit,Y> quantity_type;
202 return quantity_type::from_value(floor BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
205 template<class Unit,class Y>
206 inline
207 quantity<Unit,Y>
208 fdim BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
209 const quantity<Unit,Y>& q2)
211 using namespace detail;
213 typedef quantity<Unit,Y> quantity_type;
215 return quantity_type::from_value(fdim BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
218 #if 0
220 template<class Unit1,class Unit2,class Unit3,class Y>
221 inline
222 typename add_typeof_helper<
223 typename multiply_typeof_helper<quantity<Unit1,Y>,
224 quantity<Unit2,Y> >::type,
225 quantity<Unit3,Y> >::type
226 fma BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit1,Y>& q1,
227 const quantity<Unit2,Y>& q2,
228 const quantity<Unit3,Y>& q3)
230 using namespace detail;
232 typedef quantity<Unit1,Y> type1;
233 typedef quantity<Unit2,Y> type2;
234 typedef quantity<Unit3,Y> type3;
236 typedef typename multiply_typeof_helper<type1,type2>::type prod_type;
237 typedef typename add_typeof_helper<prod_type,type3>::type quantity_type;
239 return quantity_type::from_value(fma BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value(),q3.value()));
242 #endif
244 template<class Unit,class Y>
245 inline
246 quantity<Unit,Y>
247 fmax BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
248 const quantity<Unit,Y>& q2)
250 using namespace detail;
252 typedef quantity<Unit,Y> quantity_type;
254 return quantity_type::from_value(fmax BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
257 template<class Unit,class Y>
258 inline
259 quantity<Unit,Y>
260 fmin BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
261 const quantity<Unit,Y>& q2)
263 using namespace detail;
265 typedef quantity<Unit,Y> quantity_type;
267 return quantity_type::from_value(fmin BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
270 template<class Unit,class Y>
271 inline
272 int
273 fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
275 using boost::math::fpclassify;
277 return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
280 template<class Unit,class Y>
281 inline
282 typename root_typeof_helper<
283 typename add_typeof_helper<
284 typename power_typeof_helper<quantity<Unit,Y>,
285 static_rational<2> >::type,
286 typename power_typeof_helper<quantity<Unit,Y>,
287 static_rational<2> >::type>::type,
288 static_rational<2> >::type
289 hypot BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,const quantity<Unit,Y>& q2)
291 using boost::math::hypot;
293 typedef quantity<Unit,Y> type1;
295 typedef typename power_typeof_helper<type1,static_rational<2> >::type pow_type;
296 typedef typename add_typeof_helper<pow_type,pow_type>::type add_type;
297 typedef typename root_typeof_helper<add_type,static_rational<2> >::type quantity_type;
299 return quantity_type::from_value(hypot BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
302 // does ISO C++ support long long? g++ claims not
303 //template<class Unit,class Y>
304 //inline
305 //quantity<Unit,long long>
306 //llrint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
308 // using namespace detail;
310 // typedef quantity<Unit,long long> quantity_type;
312 // return quantity_type::from_value(llrint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
315 // does ISO C++ support long long? g++ claims not
316 //template<class Unit,class Y>
317 //inline
318 //quantity<Unit,long long>
319 //llround BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
321 // using namespace detail;
323 // typedef quantity<Unit,long long> quantity_type;
325 // return quantity_type::from_value(llround BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
328 #if 0
330 template<class Unit,class Y>
331 inline
332 quantity<Unit,Y>
333 nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
335 using namespace detail;
337 typedef quantity<Unit,Y> quantity_type;
339 return quantity_type::from_value(nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
342 #endif
344 template<class Unit,class Y>
345 inline
346 quantity<Unit,Y> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
347 const quantity<Unit,Y>& q2)
349 using boost::math::nextafter;
351 typedef quantity<Unit,Y> quantity_type;
353 return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
355 template<class Unit,class Y>
356 inline
357 quantity<Unit,Y> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
358 const quantity<Unit,Y>& q2)
360 // the only difference between nextafter and nexttowards is
361 // in the argument types. Since we are requiring identical
362 // argument types, there is no difference.
363 using boost::math::nextafter;
365 typedef quantity<Unit,Y> quantity_type;
367 return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
370 #if 0
372 template<class Unit,class Y>
373 inline
374 quantity<Unit,Y>
375 rint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
377 using namespace detail;
379 typedef quantity<Unit,Y> quantity_type;
381 return quantity_type::from_value(rint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
384 #endif
386 template<class Unit,class Y>
387 inline
388 quantity<Unit,Y>
389 round BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
391 using boost::math::round;
393 typedef quantity<Unit,Y> quantity_type;
395 return quantity_type::from_value(round BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
398 template<class Unit,class Y>
399 inline
400 int
401 signbit BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
403 using boost::math::signbit;
405 return signbit BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
408 template<class Unit,class Y>
409 inline
410 quantity<Unit,Y>
411 trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
413 using namespace detail;
415 typedef quantity<Unit,Y> quantity_type;
417 return quantity_type::from_value(trunc BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
420 template<class Unit,class Y>
421 inline
422 quantity<Unit, Y>
423 fmod(const quantity<Unit,Y>& q1, const quantity<Unit,Y>& q2)
425 using std::fmod;
427 typedef quantity<Unit,Y> quantity_type;
429 return quantity_type::from_value(fmod(q1.value(), q2.value()));
432 template<class Unit, class Y>
433 inline
434 quantity<Unit, Y>
435 modf(const quantity<Unit, Y>& q1, quantity<Unit, Y>* q2)
437 using std::modf;
439 typedef quantity<Unit,Y> quantity_type;
441 return quantity_type::from_value(modf(q1.value(), &quantity_cast<Y&>(*q2)));
444 template<class Unit, class Y, class Int>
445 inline
446 quantity<Unit, Y>
447 frexp(const quantity<Unit, Y>& q,Int* ex)
449 using std::frexp;
451 typedef quantity<Unit,Y> quantity_type;
453 return quantity_type::from_value(frexp(q.value(),ex));
456 /// For non-dimensionless quantities, integral and rational powers
457 /// and roots can be computed by @c pow<Ex> and @c root<Rt> respectively.
458 template<class S, class Y>
459 inline
460 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
461 pow(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q1,
462 const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q2)
464 using std::pow;
466 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S),Y> quantity_type;
468 return quantity_type::from_value(pow(q1.value(), q2.value()));
471 template<class S, class Y>
472 inline
473 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
474 exp(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
476 using std::exp;
478 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
480 return quantity_type::from_value(exp(q.value()));
483 template<class Unit, class Y, class Int>
484 inline
485 quantity<Unit, Y>
486 ldexp(const quantity<Unit, Y>& q,const Int& ex)
488 using std::ldexp;
490 typedef quantity<Unit,Y> quantity_type;
492 return quantity_type::from_value(ldexp(q.value(), ex));
495 template<class S, class Y>
496 inline
497 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
498 log(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
500 using std::log;
502 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
504 return quantity_type::from_value(log(q.value()));
507 template<class S, class Y>
508 inline
509 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
510 log10(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
512 using std::log10;
514 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
516 return quantity_type::from_value(log10(q.value()));
519 template<class Unit,class Y>
520 inline
521 typename root_typeof_helper<
522 quantity<Unit,Y>,
523 static_rational<2>
524 >::type
525 sqrt(const quantity<Unit,Y>& q)
527 using std::sqrt;
529 typedef typename root_typeof_helper<
530 quantity<Unit,Y>,
531 static_rational<2>
532 >::type quantity_type;
534 return quantity_type::from_value(sqrt(q.value()));
537 } // namespace units
539 } // namespace boost
541 namespace boost {
543 namespace units {
545 // trig functions with si argument/return types
547 /// cos of theta in radians
548 template<class Y>
549 typename dimensionless_quantity<si::system,Y>::type
550 cos(const quantity<si::plane_angle,Y>& theta)
552 using std::cos;
553 return cos(theta.value());
556 /// sin of theta in radians
557 template<class Y>
558 typename dimensionless_quantity<si::system,Y>::type
559 sin(const quantity<si::plane_angle,Y>& theta)
561 using std::sin;
562 return sin(theta.value());
565 /// tan of theta in radians
566 template<class Y>
567 typename dimensionless_quantity<si::system,Y>::type
568 tan(const quantity<si::plane_angle,Y>& theta)
570 using std::tan;
571 return tan(theta.value());
574 /// cos of theta in other angular units
575 template<class System,class Y>
576 typename dimensionless_quantity<System,Y>::type
577 cos(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
579 return cos(quantity<si::plane_angle,Y>(theta));
582 /// sin of theta in other angular units
583 template<class System,class Y>
584 typename dimensionless_quantity<System,Y>::type
585 sin(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
587 return sin(quantity<si::plane_angle,Y>(theta));
590 /// tan of theta in other angular units
591 template<class System,class Y>
592 typename dimensionless_quantity<System,Y>::type
593 tan(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
595 return tan(quantity<si::plane_angle,Y>(theta));
598 /// acos of dimensionless quantity returning angle in same system
599 template<class Y,class System>
600 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
601 acos(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val)
603 using std::acos;
604 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(acos(val.value())*si::radians);
607 /// asin of dimensionless quantity returning angle in same system
608 template<class Y,class System>
609 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
610 asin(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val)
612 using std::asin;
613 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(asin(val.value())*si::radians);
616 /// atan of dimensionless quantity returning angle in same system
617 template<class Y,class System>
618 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
619 atan(const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& val)
621 using std::atan;
622 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(atan(val.value())*si::radians);
625 /// atan2 of @c value_type returning angle in radians
626 template<class Y, class System>
627 quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>
628 atan2(const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& y,
629 const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& x)
631 using std::atan2;
632 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>(atan2(y.value(),x.value())*si::radians);
635 } // namespace units
637 } // namespace boost
639 #endif // BOOST_UNITS_CMATH_HPP