Ticket #6752: cmath.hpp

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