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) |
10 | |
11 | #ifndef BOOST_UNITS_CMATH_HPP |
12 | #define BOOST_UNITS_CMATH_HPP |
13 | |
14 | #include <boost/config/no_tr1/cmath.hpp> |
15 | #include <cstdlib> |
16 | |
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> |
22 | |
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> |
27 | #include <boost/units/detail/dimensionless_unit.hpp> |
28 | |
29 | #include <boost/units/systems/si/plane_angle.hpp> |
30 | |
31 | /// \file |
32 | /// \brief Overloads of functions in \<cmath\> for quantities. |
33 | /// \details Only functions for which a dimensionally-correct result type |
34 | /// can be determined are overloaded. |
35 | /// All functions work with dimensionless quantities. |
36 | |
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 :) |
40 | // |
41 | // the form using namespace detail; return(f(x)); is used |
42 | // to enable ADL for UDTs. |
43 | |
44 | namespace boost { |
45 | |
46 | namespace units { |
47 | |
48 | template<class Unit,class Y> |
49 | inline |
50 | bool |
51 | isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
52 | { |
53 | using boost::math::isfinite; |
54 | return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
55 | } |
56 | |
57 | template<class Unit,class Y> |
58 | inline |
59 | bool |
60 | isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
61 | { |
62 | using boost::math::isinf; |
63 | return isinf BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
64 | } |
65 | |
66 | template<class Unit,class Y> |
67 | inline |
68 | bool |
69 | isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
70 | { |
71 | using boost::math::isnan; |
72 | return isnan BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
73 | } |
74 | |
75 | template<class Unit,class Y> |
76 | inline |
77 | bool |
78 | isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
79 | { |
80 | using boost::math::isnormal; |
81 | return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
82 | } |
83 | |
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) |
89 | { |
90 | using namespace detail; |
91 | return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
92 | } |
93 | |
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) |
99 | { |
100 | using namespace detail; |
101 | return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
102 | } |
103 | |
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) |
109 | { |
110 | using namespace detail; |
111 | return isless BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
112 | } |
113 | |
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) |
119 | { |
120 | using namespace detail; |
121 | return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
122 | } |
123 | |
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) |
129 | { |
130 | using namespace detail; |
131 | return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
132 | } |
133 | |
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) |
139 | { |
140 | using namespace detail; |
141 | return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
142 | } |
143 | |
144 | template<class Unit,class Y> |
145 | inline |
146 | quantity<Unit,Y> |
147 | abs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
148 | { |
149 | using std::abs; |
150 | |
151 | typedef quantity<Unit,Y> quantity_type; |
152 | |
153 | return quantity_type::from_value(abs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
154 | } |
155 | |
156 | template<class Unit,class Y> |
157 | inline |
158 | quantity<Unit,Y> |
159 | ceil BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
160 | { |
161 | using std::ceil; |
162 | |
163 | typedef quantity<Unit,Y> quantity_type; |
164 | |
165 | return quantity_type::from_value(ceil BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
166 | } |
167 | |
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) |
173 | { |
174 | using boost::math::copysign; |
175 | |
176 | typedef quantity<Unit,Y> quantity_type; |
177 | |
178 | return quantity_type::from_value(copysign BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
179 | } |
180 | |
181 | template<class Unit,class Y> |
182 | inline |
183 | quantity<Unit,Y> |
184 | fabs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
185 | { |
186 | using std::fabs; |
187 | |
188 | typedef quantity<Unit,Y> quantity_type; |
189 | |
190 | return quantity_type::from_value(fabs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
191 | } |
192 | |
193 | template<class Unit,class Y> |
194 | inline |
195 | quantity<Unit,Y> |
196 | floor BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
197 | { |
198 | using std::floor; |
199 | |
200 | typedef quantity<Unit,Y> quantity_type; |
201 | |
202 | return quantity_type::from_value(floor BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
203 | } |
204 | |
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) |
210 | { |
211 | using namespace detail; |
212 | |
213 | typedef quantity<Unit,Y> quantity_type; |
214 | |
215 | return quantity_type::from_value(fdim BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
216 | } |
217 | |
218 | #if 0 |
219 | |
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) |
229 | { |
230 | using namespace detail; |
231 | |
232 | typedef quantity<Unit1,Y> type1; |
233 | typedef quantity<Unit2,Y> type2; |
234 | typedef quantity<Unit3,Y> type3; |
235 | |
236 | typedef typename multiply_typeof_helper<type1,type2>::type prod_type; |
237 | typedef typename add_typeof_helper<prod_type,type3>::type quantity_type; |
238 | |
239 | return quantity_type::from_value(fma BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value(),q3.value())); |
240 | } |
241 | |
242 | #endif |
243 | |
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) |
249 | { |
250 | using namespace detail; |
251 | |
252 | typedef quantity<Unit,Y> quantity_type; |
253 | |
254 | return quantity_type::from_value(fmax BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
255 | } |
256 | |
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) |
262 | { |
263 | using namespace detail; |
264 | |
265 | typedef quantity<Unit,Y> quantity_type; |
266 | |
267 | return quantity_type::from_value(fmin BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
268 | } |
269 | |
270 | template<class Unit,class Y> |
271 | inline |
272 | int |
273 | fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
274 | { |
275 | using boost::math::fpclassify; |
276 | |
277 | return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
278 | } |
279 | |
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) |
290 | { |
291 | using boost::math::hypot; |
292 | |
293 | typedef quantity<Unit,Y> type1; |
294 | |
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; |
298 | |
299 | return quantity_type::from_value(hypot BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
300 | } |
301 | |
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) |
307 | //{ |
308 | // using namespace detail; |
309 | // |
310 | // typedef quantity<Unit,long long> quantity_type; |
311 | // |
312 | // return quantity_type::from_value(llrint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
313 | //} |
314 | |
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) |
320 | //{ |
321 | // using namespace detail; |
322 | // |
323 | // typedef quantity<Unit,long long> quantity_type; |
324 | // |
325 | // return quantity_type::from_value(llround BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
326 | //} |
327 | |
328 | #if 0 |
329 | |
330 | template<class Unit,class Y> |
331 | inline |
332 | quantity<Unit,Y> |
333 | nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
334 | { |
335 | using namespace detail; |
336 | |
337 | typedef quantity<Unit,Y> quantity_type; |
338 | |
339 | return quantity_type::from_value(nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
340 | } |
341 | |
342 | #endif |
343 | |
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) |
348 | { |
349 | using boost::math::nextafter; |
350 | |
351 | typedef quantity<Unit,Y> quantity_type; |
352 | |
353 | return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
354 | } |
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) |
359 | { |
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; |
364 | |
365 | typedef quantity<Unit,Y> quantity_type; |
366 | |
367 | return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
368 | } |
369 | |
370 | #if 0 |
371 | |
372 | template<class Unit,class Y> |
373 | inline |
374 | quantity<Unit,Y> |
375 | rint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
376 | { |
377 | using namespace detail; |
378 | |
379 | typedef quantity<Unit,Y> quantity_type; |
380 | |
381 | return quantity_type::from_value(rint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
382 | } |
383 | |
384 | #endif |
385 | |
386 | template<class Unit,class Y> |
387 | inline |
388 | quantity<Unit,Y> |
389 | round BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
390 | { |
391 | using boost::math::round; |
392 | |
393 | typedef quantity<Unit,Y> quantity_type; |
394 | |
395 | return quantity_type::from_value(round BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
396 | } |
397 | |
398 | template<class Unit,class Y> |
399 | inline |
400 | int |
401 | signbit BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
402 | { |
403 | using boost::math::signbit; |
404 | |
405 | return signbit BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
406 | } |
407 | |
408 | template<class Unit,class Y> |
409 | inline |
410 | quantity<Unit,Y> |
411 | trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
412 | { |
413 | using namespace detail; |
414 | |
415 | typedef quantity<Unit,Y> quantity_type; |
416 | |
417 | return quantity_type::from_value(trunc BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
418 | } |
419 | |
420 | template<class Unit,class Y> |
421 | inline |
422 | quantity<Unit, Y> |
423 | fmod(const quantity<Unit,Y>& q1, const quantity<Unit,Y>& q2) |
424 | { |
425 | using std::fmod; |
426 | |
427 | typedef quantity<Unit,Y> quantity_type; |
428 | |
429 | return quantity_type::from_value(fmod(q1.value(), q2.value())); |
430 | } |
431 | |
432 | template<class Unit, class Y> |
433 | inline |
434 | quantity<Unit, Y> |
435 | modf(const quantity<Unit, Y>& q1, quantity<Unit, Y>* q2) |
436 | { |
437 | using std::modf; |
438 | |
439 | typedef quantity<Unit,Y> quantity_type; |
440 | |
441 | return quantity_type::from_value(modf(q1.value(), &quantity_cast<Y&>(*q2))); |
442 | } |
443 | |
444 | template<class Unit, class Y, class Int> |
445 | inline |
446 | quantity<Unit, Y> |
447 | frexp(const quantity<Unit, Y>& q,Int* ex) |
448 | { |
449 | using std::frexp; |
450 | |
451 | typedef quantity<Unit,Y> quantity_type; |
452 | |
453 | return quantity_type::from_value(frexp(q.value(),ex)); |
454 | } |
455 | |
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) |
463 | { |
464 | using std::pow; |
465 | |
466 | typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S),Y> quantity_type; |
467 | |
468 | return quantity_type::from_value(pow(q1.value(), q2.value())); |
469 | } |
470 | |
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) |
475 | { |
476 | using std::exp; |
477 | |
478 | typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
479 | |
480 | return quantity_type::from_value(exp(q.value())); |
481 | } |
482 | |
483 | template<class Unit, class Y, class Int> |
484 | inline |
485 | quantity<Unit, Y> |
486 | ldexp(const quantity<Unit, Y>& q,const Int& ex) |
487 | { |
488 | using std::ldexp; |
489 | |
490 | typedef quantity<Unit,Y> quantity_type; |
491 | |
492 | return quantity_type::from_value(ldexp(q.value(), ex)); |
493 | } |
494 | |
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) |
499 | { |
500 | using std::log; |
501 | |
502 | typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
503 | |
504 | return quantity_type::from_value(log(q.value())); |
505 | } |
506 | |
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) |
511 | { |
512 | using std::log10; |
513 | |
514 | typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
515 | |
516 | return quantity_type::from_value(log10(q.value())); |
517 | } |
518 | |
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) |
526 | { |
527 | using std::sqrt; |
528 | |
529 | typedef typename root_typeof_helper< |
530 | quantity<Unit,Y>, |
531 | static_rational<2> |
532 | >::type quantity_type; |
533 | |
534 | return quantity_type::from_value(sqrt(q.value())); |
535 | } |
536 | |
537 | } // namespace units |
538 | |
539 | } // namespace boost |
540 | |
541 | namespace boost { |
542 | |
543 | namespace units { |
544 | |
545 | // trig functions with si argument/return types |
546 | |
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) |
551 | { |
552 | using std::cos; |
553 | return cos(theta.value()); |
554 | } |
555 | |
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) |
560 | { |
561 | using std::sin; |
562 | return sin(theta.value()); |
563 | } |
564 | |
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) |
569 | { |
570 | using std::tan; |
571 | return tan(theta.value()); |
572 | } |
573 | |
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) |
578 | { |
579 | return cos(quantity<si::plane_angle,Y>(theta)); |
580 | } |
581 | |
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) |
586 | { |
587 | return sin(quantity<si::plane_angle,Y>(theta)); |
588 | } |
589 | |
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) |
594 | { |
595 | return tan(quantity<si::plane_angle,Y>(theta)); |
596 | } |
597 | |
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) |
602 | { |
603 | using std::acos; |
604 | return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(acos(val.value())*si::radians); |
605 | } |
606 | |
607 | /// acos of dimensionless quantity returning angle in radians |
608 | template<class Y> |
609 | quantity<angle::radian_base_unit::unit_type,Y> |
610 | acos(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val) |
611 | { |
612 | using std::acos; |
613 | return quantity<angle::radian_base_unit::unit_type,Y>::from_value(acos(val.value())); |
614 | } |
615 | |
616 | /// asin 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 | asin(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val) |
620 | { |
621 | using std::asin; |
622 | return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(asin(val.value())*si::radians); |
623 | } |
624 | |
625 | /// asin of dimensionless quantity returning angle in radians |
626 | template<class Y> |
627 | quantity<angle::radian_base_unit::unit_type,Y> |
628 | asin(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val) |
629 | { |
630 | using std::asin; |
631 | return quantity<angle::radian_base_unit::unit_type,Y>::from_value(asin(val.value())); |
632 | } |
633 | |
634 | /// atan of dimensionless quantity returning angle in same system |
635 | template<class Y,class System> |
636 | quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y> |
637 | atan(const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& val) |
638 | { |
639 | using std::atan; |
640 | return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(atan(val.value())*si::radians); |
641 | } |
642 | |
643 | /// atan of dimensionless quantity returning angle in radians |
644 | template<class Y> |
645 | quantity<angle::radian_base_unit::unit_type,Y> |
646 | atan(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>, Y>& val) |
647 | { |
648 | using std::atan; |
649 | return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan(val.value())); |
650 | } |
651 | |
652 | /// atan2 of @c value_type returning angle in radians |
653 | template<class Y, class Dimension, class System> |
654 | quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y> |
655 | atan2(const quantity<unit<Dimension, homogeneous_system<System> >, Y>& y, |
656 | const quantity<unit<Dimension, homogeneous_system<System> >, Y>& x) |
657 | { |
658 | using std::atan2; |
659 | return quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>(atan2(y.value(),x.value())*si::radians); |
660 | } |
661 | |
662 | /// atan2 of @c value_type returning angle in radians |
663 | template<class Y, class Dimension, class System> |
664 | quantity<angle::radian_base_unit::unit_type,Y> |
665 | atan2(const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& y, |
666 | const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& x) |
667 | { |
668 | using std::atan2; |
669 | return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan2(y.value(),x.value())); |
670 | } |
671 | |
672 | } // namespace units |
673 | |
674 | } // namespace boost |
675 | |
676 | #endif // BOOST_UNITS_CMATH_HPP |
677 | |