cmath.hpp 20 KB

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