]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/units/cmath.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / units / cmath.hpp
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 BOOST_CONSTEXPR
51 bool
52 isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
53 {
54 using boost::math::isfinite;
55 return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
56 }
57
58 template<class Unit,class Y>
59 inline
60 BOOST_CONSTEXPR
61 bool
62 isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
63 {
64 using boost::math::isinf;
65 return isinf BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
66 }
67
68 template<class Unit,class Y>
69 inline
70 BOOST_CONSTEXPR
71 bool
72 isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
73 {
74 using boost::math::isnan;
75 return isnan BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
76 }
77
78 template<class Unit,class Y>
79 inline
80 BOOST_CONSTEXPR
81 bool
82 isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
83 {
84 using boost::math::isnormal;
85 return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
86 }
87
88 template<class Unit,class Y>
89 inline
90 BOOST_CONSTEXPR
91 bool
92 isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
93 const quantity<Unit,Y>& q2)
94 {
95 using namespace detail;
96 return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
97 }
98
99 template<class Unit,class Y>
100 inline
101 BOOST_CONSTEXPR
102 bool
103 isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
104 const quantity<Unit,Y>& q2)
105 {
106 using namespace detail;
107 return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
108 }
109
110 template<class Unit,class Y>
111 inline
112 BOOST_CONSTEXPR
113 bool
114 isless BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
115 const quantity<Unit,Y>& q2)
116 {
117 using namespace detail;
118 return isless BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
119 }
120
121 template<class Unit,class Y>
122 inline
123 BOOST_CONSTEXPR
124 bool
125 islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
126 const quantity<Unit,Y>& q2)
127 {
128 using namespace detail;
129 return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
130 }
131
132 template<class Unit,class Y>
133 inline
134 BOOST_CONSTEXPR
135 bool
136 islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
137 const quantity<Unit,Y>& q2)
138 {
139 using namespace detail;
140 return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
141 }
142
143 template<class Unit,class Y>
144 inline
145 BOOST_CONSTEXPR
146 bool
147 isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
148 const quantity<Unit,Y>& q2)
149 {
150 using namespace detail;
151 return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value());
152 }
153
154 template<class Unit,class Y>
155 inline
156 BOOST_CONSTEXPR
157 quantity<Unit,Y>
158 abs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
159 {
160 using std::abs;
161
162 typedef quantity<Unit,Y> quantity_type;
163
164 return quantity_type::from_value(abs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
165 }
166
167 template<class Unit,class Y>
168 inline
169 BOOST_CONSTEXPR
170 quantity<Unit,Y>
171 ceil BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
172 {
173 using std::ceil;
174
175 typedef quantity<Unit,Y> quantity_type;
176
177 return quantity_type::from_value(ceil BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
178 }
179
180 template<class Unit,class Y>
181 inline
182 BOOST_CONSTEXPR
183 quantity<Unit,Y>
184 copysign BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
185 const quantity<Unit,Y>& q2)
186 {
187 using boost::math::copysign;
188
189 typedef quantity<Unit,Y> quantity_type;
190
191 return quantity_type::from_value(copysign BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
192 }
193
194 template<class Unit,class Y>
195 inline
196 BOOST_CONSTEXPR
197 quantity<Unit,Y>
198 fabs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
199 {
200 using std::fabs;
201
202 typedef quantity<Unit,Y> quantity_type;
203
204 return quantity_type::from_value(fabs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
205 }
206
207 template<class Unit,class Y>
208 inline
209 BOOST_CONSTEXPR
210 quantity<Unit,Y>
211 floor BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
212 {
213 using std::floor;
214
215 typedef quantity<Unit,Y> quantity_type;
216
217 return quantity_type::from_value(floor BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
218 }
219
220 template<class Unit,class Y>
221 inline
222 BOOST_CONSTEXPR
223 quantity<Unit,Y>
224 fdim BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
225 const quantity<Unit,Y>& q2)
226 {
227 using namespace detail;
228
229 typedef quantity<Unit,Y> quantity_type;
230
231 return quantity_type::from_value(fdim BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
232 }
233
234 #if 0
235
236 template<class Unit1,class Unit2,class Unit3,class Y>
237 inline
238 BOOST_CONSTEXPR
239 typename add_typeof_helper<
240 typename multiply_typeof_helper<quantity<Unit1,Y>,
241 quantity<Unit2,Y> >::type,
242 quantity<Unit3,Y> >::type
243 fma BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit1,Y>& q1,
244 const quantity<Unit2,Y>& q2,
245 const quantity<Unit3,Y>& q3)
246 {
247 using namespace detail;
248
249 typedef quantity<Unit1,Y> type1;
250 typedef quantity<Unit2,Y> type2;
251 typedef quantity<Unit3,Y> type3;
252
253 typedef typename multiply_typeof_helper<type1,type2>::type prod_type;
254 typedef typename add_typeof_helper<prod_type,type3>::type quantity_type;
255
256 return quantity_type::from_value(fma BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value(),q3.value()));
257 }
258
259 #endif
260
261 template<class Unit,class Y>
262 inline
263 BOOST_CONSTEXPR
264 quantity<Unit,Y>
265 fmax BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
266 const quantity<Unit,Y>& q2)
267 {
268 using namespace detail;
269
270 typedef quantity<Unit,Y> quantity_type;
271
272 return quantity_type::from_value(fmax BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
273 }
274
275 template<class Unit,class Y>
276 inline
277 BOOST_CONSTEXPR
278 quantity<Unit,Y>
279 fmin BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
280 const quantity<Unit,Y>& q2)
281 {
282 using namespace detail;
283
284 typedef quantity<Unit,Y> quantity_type;
285
286 return quantity_type::from_value(fmin BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
287 }
288
289 template<class Unit,class Y>
290 inline
291 BOOST_CONSTEXPR
292 int
293 fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
294 {
295 using boost::math::fpclassify;
296
297 return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
298 }
299
300 template<class Unit,class Y>
301 inline
302 BOOST_CONSTEXPR
303 typename root_typeof_helper<
304 typename add_typeof_helper<
305 typename power_typeof_helper<quantity<Unit,Y>,
306 static_rational<2> >::type,
307 typename power_typeof_helper<quantity<Unit,Y>,
308 static_rational<2> >::type>::type,
309 static_rational<2> >::type
310 hypot BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,const quantity<Unit,Y>& q2)
311 {
312 using boost::math::hypot;
313
314 typedef quantity<Unit,Y> type1;
315
316 typedef typename power_typeof_helper<type1,static_rational<2> >::type pow_type;
317 typedef typename add_typeof_helper<pow_type,pow_type>::type add_type;
318 typedef typename root_typeof_helper<add_type,static_rational<2> >::type quantity_type;
319
320 return quantity_type::from_value(hypot BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
321 }
322
323 // does ISO C++ support long long? g++ claims not
324 //template<class Unit,class Y>
325 //inline
326 //BOOST_CONSTEXPR
327 //quantity<Unit,long long>
328 //llrint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
329 //{
330 // using namespace detail;
331 //
332 // typedef quantity<Unit,long long> quantity_type;
333 //
334 // return quantity_type::from_value(llrint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
335 //}
336
337 // does ISO C++ support long long? g++ claims not
338 //template<class Unit,class Y>
339 //inline
340 //BOOST_CONSTEXPR
341 //quantity<Unit,long long>
342 //llround BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
343 //{
344 // using namespace detail;
345 //
346 // typedef quantity<Unit,long long> quantity_type;
347 //
348 // return quantity_type::from_value(llround BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
349 //}
350
351 #if 0
352
353 template<class Unit,class Y>
354 inline
355 BOOST_CONSTEXPR
356 quantity<Unit,Y>
357 nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
358 {
359 using namespace detail;
360
361 typedef quantity<Unit,Y> quantity_type;
362
363 return quantity_type::from_value(nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
364 }
365
366 #endif
367
368 template<class Unit,class Y>
369 inline
370 BOOST_CONSTEXPR
371 quantity<Unit,Y> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
372 const quantity<Unit,Y>& q2)
373 {
374 using boost::math::nextafter;
375
376 typedef quantity<Unit,Y> quantity_type;
377
378 return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
379 }
380 template<class Unit,class Y>
381 inline
382 BOOST_CONSTEXPR
383 quantity<Unit,Y> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,
384 const quantity<Unit,Y>& q2)
385 {
386 // the only difference between nextafter and nexttowards is
387 // in the argument types. Since we are requiring identical
388 // argument types, there is no difference.
389 using boost::math::nextafter;
390
391 typedef quantity<Unit,Y> quantity_type;
392
393 return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()));
394 }
395
396 #if 0
397
398 template<class Unit,class Y>
399 inline
400 BOOST_CONSTEXPR
401 quantity<Unit,Y>
402 rint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
403 {
404 using namespace detail;
405
406 typedef quantity<Unit,Y> quantity_type;
407
408 return quantity_type::from_value(rint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
409 }
410
411 #endif
412
413 template<class Unit,class Y>
414 inline
415 BOOST_CONSTEXPR
416 quantity<Unit,Y>
417 round BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
418 {
419 using boost::math::round;
420
421 typedef quantity<Unit,Y> quantity_type;
422
423 return quantity_type::from_value(round BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
424 }
425
426 template<class Unit,class Y>
427 inline
428 BOOST_CONSTEXPR
429 int
430 signbit BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
431 {
432 using boost::math::signbit;
433
434 return signbit BOOST_PREVENT_MACRO_SUBSTITUTION (q.value());
435 }
436
437 template<class Unit,class Y>
438 inline
439 BOOST_CONSTEXPR
440 quantity<Unit,Y>
441 trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q)
442 {
443 using namespace detail;
444
445 typedef quantity<Unit,Y> quantity_type;
446
447 return quantity_type::from_value(trunc BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()));
448 }
449
450 template<class Unit,class Y>
451 inline
452 BOOST_CONSTEXPR
453 quantity<Unit, Y>
454 fmod(const quantity<Unit,Y>& q1, const quantity<Unit,Y>& q2)
455 {
456 using std::fmod;
457
458 typedef quantity<Unit,Y> quantity_type;
459
460 return quantity_type::from_value(fmod(q1.value(), q2.value()));
461 }
462
463 template<class Unit, class Y>
464 inline
465 BOOST_CONSTEXPR
466 quantity<Unit, Y>
467 modf(const quantity<Unit, Y>& q1, quantity<Unit, Y>* q2)
468 {
469 using std::modf;
470
471 typedef quantity<Unit,Y> quantity_type;
472
473 return quantity_type::from_value(modf(q1.value(), &quantity_cast<Y&>(*q2)));
474 }
475
476 template<class Unit, class Y, class Int>
477 inline
478 BOOST_CONSTEXPR
479 quantity<Unit, Y>
480 frexp(const quantity<Unit, Y>& q,Int* ex)
481 {
482 using std::frexp;
483
484 typedef quantity<Unit,Y> quantity_type;
485
486 return quantity_type::from_value(frexp(q.value(),ex));
487 }
488
489 /// For non-dimensionless quantities, integral and rational powers
490 /// and roots can be computed by @c pow<Ex> and @c root<Rt> respectively.
491 template<class S, class Y>
492 inline
493 BOOST_CONSTEXPR
494 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
495 pow(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q1,
496 const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q2)
497 {
498 using std::pow;
499
500 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S),Y> quantity_type;
501
502 return quantity_type::from_value(pow(q1.value(), q2.value()));
503 }
504
505 template<class S, class Y>
506 inline
507 BOOST_CONSTEXPR
508 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
509 exp(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
510 {
511 using std::exp;
512
513 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
514
515 return quantity_type::from_value(exp(q.value()));
516 }
517
518 template<class Unit, class Y, class Int>
519 inline
520 BOOST_CONSTEXPR
521 quantity<Unit, Y>
522 ldexp(const quantity<Unit, Y>& q,const Int& ex)
523 {
524 using std::ldexp;
525
526 typedef quantity<Unit,Y> quantity_type;
527
528 return quantity_type::from_value(ldexp(q.value(), ex));
529 }
530
531 template<class S, class Y>
532 inline
533 BOOST_CONSTEXPR
534 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
535 log(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
536 {
537 using std::log;
538
539 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
540
541 return quantity_type::from_value(log(q.value()));
542 }
543
544 template<class S, class Y>
545 inline
546 BOOST_CONSTEXPR
547 quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
548 log10(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q)
549 {
550 using std::log10;
551
552 typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type;
553
554 return quantity_type::from_value(log10(q.value()));
555 }
556
557 template<class Unit,class Y>
558 inline
559 BOOST_CONSTEXPR
560 typename root_typeof_helper<
561 quantity<Unit,Y>,
562 static_rational<2>
563 >::type
564 sqrt(const quantity<Unit,Y>& q)
565 {
566 using std::sqrt;
567
568 typedef typename root_typeof_helper<
569 quantity<Unit,Y>,
570 static_rational<2>
571 >::type quantity_type;
572
573 return quantity_type::from_value(sqrt(q.value()));
574 }
575
576 } // namespace units
577
578 } // namespace boost
579
580 namespace boost {
581
582 namespace units {
583
584 // trig functions with si argument/return types
585
586 /// cos of theta in radians
587 template<class Y>
588 BOOST_CONSTEXPR
589 typename dimensionless_quantity<si::system,Y>::type
590 cos(const quantity<si::plane_angle,Y>& theta)
591 {
592 using std::cos;
593 return cos(theta.value());
594 }
595
596 /// sin of theta in radians
597 template<class Y>
598 BOOST_CONSTEXPR
599 typename dimensionless_quantity<si::system,Y>::type
600 sin(const quantity<si::plane_angle,Y>& theta)
601 {
602 using std::sin;
603 return sin(theta.value());
604 }
605
606 /// tan of theta in radians
607 template<class Y>
608 BOOST_CONSTEXPR
609 typename dimensionless_quantity<si::system,Y>::type
610 tan(const quantity<si::plane_angle,Y>& theta)
611 {
612 using std::tan;
613 return tan(theta.value());
614 }
615
616 /// cos of theta in other angular units
617 template<class System,class Y>
618 BOOST_CONSTEXPR
619 typename dimensionless_quantity<System,Y>::type
620 cos(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
621 {
622 return cos(quantity<si::plane_angle,Y>(theta));
623 }
624
625 /// sin of theta in other angular units
626 template<class System,class Y>
627 BOOST_CONSTEXPR
628 typename dimensionless_quantity<System,Y>::type
629 sin(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
630 {
631 return sin(quantity<si::plane_angle,Y>(theta));
632 }
633
634 /// tan of theta in other angular units
635 template<class System,class Y>
636 BOOST_CONSTEXPR
637 typename dimensionless_quantity<System,Y>::type
638 tan(const quantity<unit<plane_angle_dimension,System>,Y>& theta)
639 {
640 return tan(quantity<si::plane_angle,Y>(theta));
641 }
642
643 /// acos of dimensionless quantity returning angle in same system
644 template<class Y,class System>
645 BOOST_CONSTEXPR
646 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
647 acos(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val)
648 {
649 using std::acos;
650 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(acos(val.value())*si::radians);
651 }
652
653 /// acos of dimensionless quantity returning angle in radians
654 template<class Y>
655 BOOST_CONSTEXPR
656 quantity<angle::radian_base_unit::unit_type,Y>
657 acos(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val)
658 {
659 using std::acos;
660 return quantity<angle::radian_base_unit::unit_type,Y>::from_value(acos(val.value()));
661 }
662
663 /// asin of dimensionless quantity returning angle in same system
664 template<class Y,class System>
665 BOOST_CONSTEXPR
666 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
667 asin(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val)
668 {
669 using std::asin;
670 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(asin(val.value())*si::radians);
671 }
672
673 /// asin of dimensionless quantity returning angle in radians
674 template<class Y>
675 BOOST_CONSTEXPR
676 quantity<angle::radian_base_unit::unit_type,Y>
677 asin(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val)
678 {
679 using std::asin;
680 return quantity<angle::radian_base_unit::unit_type,Y>::from_value(asin(val.value()));
681 }
682
683 /// atan of dimensionless quantity returning angle in same system
684 template<class Y,class System>
685 BOOST_CONSTEXPR
686 quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
687 atan(const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& val)
688 {
689 using std::atan;
690 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(atan(val.value())*si::radians);
691 }
692
693 /// atan of dimensionless quantity returning angle in radians
694 template<class Y>
695 BOOST_CONSTEXPR
696 quantity<angle::radian_base_unit::unit_type,Y>
697 atan(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>, Y>& val)
698 {
699 using std::atan;
700 return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan(val.value()));
701 }
702
703 /// atan2 of @c value_type returning angle in radians
704 template<class Y, class Dimension, class System>
705 BOOST_CONSTEXPR
706 quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>
707 atan2(const quantity<unit<Dimension, homogeneous_system<System> >, Y>& y,
708 const quantity<unit<Dimension, homogeneous_system<System> >, Y>& x)
709 {
710 using std::atan2;
711 return quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>(atan2(y.value(),x.value())*si::radians);
712 }
713
714 /// atan2 of @c value_type returning angle in radians
715 template<class Y, class Dimension, class System>
716 BOOST_CONSTEXPR
717 quantity<angle::radian_base_unit::unit_type,Y>
718 atan2(const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& y,
719 const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& x)
720 {
721 using std::atan2;
722 return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan2(y.value(),x.value()));
723 }
724
725 } // namespace units
726
727 } // namespace boost
728
729 #endif // BOOST_UNITS_CMATH_HPP