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
44namespace boost {
45
46namespace units {
47
48template<class Unit,class Y>
49inline
50BOOST_CONSTEXPR
51bool
52isfinite 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
58template<class Unit,class Y>
59inline
60BOOST_CONSTEXPR
61bool
62isinf 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
68template<class Unit,class Y>
69inline
70BOOST_CONSTEXPR
71bool
72isnan 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
78template<class Unit,class Y>
79inline
80BOOST_CONSTEXPR
81bool
82isnormal 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
88template<class Unit,class Y>
89inline
90BOOST_CONSTEXPR
91bool
92isgreater 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
99template<class Unit,class Y>
100inline
101BOOST_CONSTEXPR
102bool
103isgreaterequal 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
110template<class Unit,class Y>
111inline
112BOOST_CONSTEXPR
113bool
114isless 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
121template<class Unit,class Y>
122inline
123BOOST_CONSTEXPR
124bool
125islessequal 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
132template<class Unit,class Y>
133inline
134BOOST_CONSTEXPR
135bool
136islessgreater 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
143template<class Unit,class Y>
144inline
145BOOST_CONSTEXPR
146bool
147isunordered 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
154template<class Unit,class Y>
155inline
156BOOST_CONSTEXPR
157quantity<Unit,Y>
158abs 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
167template<class Unit,class Y>
168inline
169BOOST_CONSTEXPR
170quantity<Unit,Y>
171ceil 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
180template<class Unit,class Y>
181inline
182BOOST_CONSTEXPR
183quantity<Unit,Y>
184copysign 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
194template<class Unit,class Y>
195inline
196BOOST_CONSTEXPR
197quantity<Unit,Y>
198fabs 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
207template<class Unit,class Y>
208inline
209BOOST_CONSTEXPR
210quantity<Unit,Y>
211floor 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
220template<class Unit,class Y>
221inline
222BOOST_CONSTEXPR
223quantity<Unit,Y>
224fdim 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
236template<class Unit1,class Unit2,class Unit3,class Y>
237inline
238BOOST_CONSTEXPR
239typename add_typeof_helper<
240 typename multiply_typeof_helper<quantity<Unit1,Y>,
241 quantity<Unit2,Y> >::type,
242 quantity<Unit3,Y> >::type
243fma 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
261template<class Unit,class Y>
262inline
263BOOST_CONSTEXPR
264quantity<Unit,Y>
265fmax 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
275template<class Unit,class Y>
276inline
277BOOST_CONSTEXPR
278quantity<Unit,Y>
279fmin 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
289template<class Unit,class Y>
290inline
291BOOST_CONSTEXPR
292int
293fpclassify 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
300template<class Unit,class Y>
301inline
302BOOST_CONSTEXPR
303typename 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
310hypot 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
353template<class Unit,class Y>
354inline
355BOOST_CONSTEXPR
356quantity<Unit,Y>
357nearbyint 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
368template<class Unit,class Y>
369inline
370BOOST_CONSTEXPR
371quantity<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}
380template<class Unit,class Y>
381inline
382BOOST_CONSTEXPR
383quantity<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
398template<class Unit,class Y>
399inline
400BOOST_CONSTEXPR
401quantity<Unit,Y>
402rint 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
413template<class Unit,class Y>
414inline
415BOOST_CONSTEXPR
416quantity<Unit,Y>
417round 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
426template<class Unit,class Y>
427inline
428BOOST_CONSTEXPR
429int
430signbit 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
437template<class Unit,class Y>
438inline
439BOOST_CONSTEXPR
440quantity<Unit,Y>
441trunc 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
450template<class Unit,class Y>
451inline
452BOOST_CONSTEXPR
453quantity<Unit, Y>
454fmod(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
463template<class Unit, class Y>
464inline
465BOOST_CONSTEXPR
466quantity<Unit, Y>
467modf(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
476template<class Unit, class Y, class Int>
477inline
478BOOST_CONSTEXPR
479quantity<Unit, Y>
480frexp(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.
491template<class S, class Y>
492inline
493BOOST_CONSTEXPR
494quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
495pow(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
505template<class S, class Y>
506inline
507BOOST_CONSTEXPR
508quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
509exp(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
518template<class Unit, class Y, class Int>
519inline
520BOOST_CONSTEXPR
521quantity<Unit, Y>
522ldexp(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
531template<class S, class Y>
532inline
533BOOST_CONSTEXPR
534quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
535log(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
544template<class S, class Y>
545inline
546BOOST_CONSTEXPR
547quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>
548log10(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
557template<class Unit,class Y>
558inline
559BOOST_CONSTEXPR
560typename root_typeof_helper<
561 quantity<Unit,Y>,
562 static_rational<2>
563 >::type
564sqrt(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
580namespace boost {
581
582namespace units {
583
584// trig functions with si argument/return types
585
586/// cos of theta in radians
587template<class Y>
588BOOST_CONSTEXPR
589typename dimensionless_quantity<si::system,Y>::type
590cos(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
597template<class Y>
598BOOST_CONSTEXPR
599typename dimensionless_quantity<si::system,Y>::type
600sin(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
607template<class Y>
608BOOST_CONSTEXPR
609typename dimensionless_quantity<si::system,Y>::type
610tan(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
617template<class System,class Y>
618BOOST_CONSTEXPR
619typename dimensionless_quantity<System,Y>::type
620cos(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
626template<class System,class Y>
627BOOST_CONSTEXPR
628typename dimensionless_quantity<System,Y>::type
629sin(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
635template<class System,class Y>
636BOOST_CONSTEXPR
637typename dimensionless_quantity<System,Y>::type
638tan(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
644template<class Y,class System>
645BOOST_CONSTEXPR
646quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
647acos(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
654template<class Y>
655BOOST_CONSTEXPR
656quantity<angle::radian_base_unit::unit_type,Y>
657acos(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
664template<class Y,class System>
665BOOST_CONSTEXPR
666quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
667asin(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
674template<class Y>
675BOOST_CONSTEXPR
676quantity<angle::radian_base_unit::unit_type,Y>
677asin(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
684template<class Y,class System>
685BOOST_CONSTEXPR
686quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>
687atan(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
694template<class Y>
695BOOST_CONSTEXPR
696quantity<angle::radian_base_unit::unit_type,Y>
697atan(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
704template<class Y, class Dimension, class System>
705BOOST_CONSTEXPR
706quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>
707atan2(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
715template<class Y, class Dimension, class System>
716BOOST_CONSTEXPR
717quantity<angle::radian_base_unit::unit_type,Y>
718atan2(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
730

source code of boost/libs/units/include/boost/units/cmath.hpp